Ensure proper sorting of 'choices' attribute on ChoiceField

This commit is contained in:
Tom Christie 2014-09-25 10:49:25 +01:00
parent fb1546ee50
commit 1420c76453
3 changed files with 10 additions and 7 deletions

View File

@ -2,6 +2,7 @@ from django.conf import settings
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils import timezone from django.utils import timezone
from django.utils.datastructures import SortedDict
from django.utils.dateparse import parse_date, parse_datetime, parse_time from django.utils.dateparse import parse_date, parse_datetime, parse_time
from django.utils.encoding import is_protected_type from django.utils.encoding import is_protected_type
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -166,7 +167,7 @@ class Field(object):
# my_field = serializer.CharField(source='my_field') # my_field = serializer.CharField(source='my_field')
assert self._kwargs.get('source') != field_name, ( assert self._kwargs.get('source') != field_name, (
"It is redundant to specify `source='%s'` on field '%s' in " "It is redundant to specify `source='%s'` on field '%s' in "
"serializer '%s', as it is the same the field name. " "serializer '%s', because it is the same as the field name. "
"Remove the `source` keyword argument." % "Remove the `source` keyword argument." %
(field_name, self.__class__.__name__, parent.__class__.__name__) (field_name, self.__class__.__name__, parent.__class__.__name__)
) )
@ -303,6 +304,7 @@ class BooleanField(Field):
'invalid': _('`{input}` is not a valid boolean.') 'invalid': _('`{input}` is not a valid boolean.')
} }
default_empty_html = False default_empty_html = False
initial = False
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True)) TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False)) FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
@ -365,6 +367,7 @@ class CharField(Field):
'blank': _('This field may not be blank.') 'blank': _('This field may not be blank.')
} }
default_empty_html = '' default_empty_html = ''
initial = ''
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.allow_blank = kwargs.pop('allow_blank', False) self.allow_blank = kwargs.pop('allow_blank', False)
@ -775,9 +778,9 @@ class ChoiceField(Field):
for item in choices for item in choices
] ]
if all(pairs): if all(pairs):
self.choices = dict([(key, display_value) for key, display_value in choices]) self.choices = SortedDict([(key, display_value) for key, display_value in choices])
else: else:
self.choices = dict([(item, item) for item in choices]) self.choices = SortedDict([(item, item) for item in choices])
# Map the string representation of choices to the underlying value. # Map the string representation of choices to the underlying value.
# Allows us to deal with eg. integer choices while supporting either # Allows us to deal with eg. integer choices while supporting either

View File

@ -76,8 +76,8 @@ class TestFieldOptions:
ExampleSerializer() ExampleSerializer()
assert str(exc_info.value) == ( assert str(exc_info.value) == (
"It is redundant to specify `source='example_field'` on field " "It is redundant to specify `source='example_field'` on field "
"'CharField' in serializer 'ExampleSerializer', as it is the " "'CharField' in serializer 'ExampleSerializer', because it is the "
"same the field name. Remove the `source` keyword argument." "same as the field name. Remove the `source` keyword argument."
) )

View File

@ -84,9 +84,9 @@ class TestMetadata:
'read_only': False, 'read_only': False,
'label': 'Choice field', 'label': 'Choice field',
'choices': [ 'choices': [
{'display_name': 'blue', 'value': 'blue'}, {'display_name': 'red', 'value': 'red'},
{'display_name': 'green', 'value': 'green'}, {'display_name': 'green', 'value': 'green'},
{'display_name': 'red', 'value': 'red'} {'display_name': 'blue', 'value': 'blue'}
] ]
}, },
'integer_field': { 'integer_field': {