Ticket #5481: choicefield_correct_type.2.diff

File choicefield_correct_type.2.diff, 5.5 KB (added by rcoup, 7 years ago)

a slightly cleaner implementation

  • django/newforms/fields.py

     
    479479        # choices can be any iterable, but we call list() on it because
    480480        # it will be consumed more than once.
    481481        self._choices = self.widget.choices = list(value)
     482        self._choices_idx = dict([(smart_unicode(k),k) for k, v in self._choices])
    482483
    483484    choices = property(_get_choices, _set_choices)
    484485
     
    492493        value = smart_unicode(value)
    493494        if value == u'':
    494495            return value
    495         valid_values = set([smart_unicode(k) for k, v in self.choices])
    496         if value not in valid_values:
     496       
     497        if value not in self._choices_idx:
    497498            raise ValidationError(ugettext(u'Select a valid choice. That choice is not one of the available choices.'))
    498         return value
     499        return self._choices_idx[value]
    499500
    500501class MultipleChoiceField(ChoiceField):
    501502    hidden_widget = MultipleHiddenInput
     
    511512            return []
    512513        if not isinstance(value, (list, tuple)):
    513514            raise ValidationError(ugettext(u'Enter a list of values.'))
    514         new_value = [smart_unicode(val) for val in value]
    515515        # Validate that each value in the value list is in self.choices.
    516         valid_values = set([smart_unicode(k) for k, v in self.choices])
    517         for val in new_value:
    518             if val not in valid_values:
    519                 raise ValidationError(ugettext(u'Select a valid choice. %s is not one of the available choices.') % val)
    520         return new_value
     516        try:
     517            return [self._choices_idx[smart_unicode(val)] for val in value]
     518        except KeyError:
     519            raise ValidationError(ugettext(u'Select a valid choice. %s is not one of the available choices.') % val)
    521520
    522521class ComboField(Field):
    523522    """
  • tests/regressiontests/forms/tests.py

     
    17651765...
    17661766ValidationError: [u'This field is required.']
    17671767>>> f.clean(1)
    1768 u'1'
     1768'1'
    17691769>>> f.clean('1')
    1770 u'1'
     1770'1'
    17711771>>> f.clean('3')
    17721772Traceback (most recent call last):
    17731773...
     
    17791779>>> f.clean(None)
    17801780u''
    17811781>>> f.clean(1)
    1782 u'1'
     1782'1'
    17831783>>> f.clean('1')
    1784 u'1'
     1784'1'
    17851785>>> f.clean('3')
    17861786Traceback (most recent call last):
    17871787...
     
    17891789
    17901790>>> f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')])
    17911791>>> f.clean('J')
    1792 u'J'
     1792'J'
    17931793>>> f.clean('John')
    17941794Traceback (most recent call last):
    17951795...
    17961796ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
    17971797
     1798>>> f = ChoiceField(choices=[(1, 'John'), (2, 'Paul')])
     1799>>> f.clean('1')
     18001
     1801>>> f.clean(1)
     18021
     1803
     1804>>> f = ChoiceField(choices=[(u'1', 'John'), (2, 'Paul')])
     1805>>> f.clean('1')
     1806u'1'
     1807>>> f.clean(1)
     1808u'1'
     1809
    17981810# NullBooleanField ############################################################
    17991811
    18001812>>> f = NullBooleanField()
     
    18211833...
    18221834ValidationError: [u'This field is required.']
    18231835>>> f.clean([1])
    1824 [u'1']
     1836['1']
    18251837>>> f.clean(['1'])
    1826 [u'1']
     1838['1']
    18271839>>> f.clean(['1', '2'])
    1828 [u'1', u'2']
     1840['1', '2']
    18291841>>> f.clean([1, '2'])
    1830 [u'1', u'2']
     1842['1', '2']
    18311843>>> f.clean((1, '2'))
    1832 [u'1', u'2']
     1844['1', '2']
    18331845>>> f.clean('hello')
    18341846Traceback (most recent call last):
    18351847...
     
    18531865>>> f.clean(None)
    18541866[]
    18551867>>> f.clean([1])
    1856 [u'1']
     1868['1']
    18571869>>> f.clean(['1'])
    1858 [u'1']
     1870['1']
    18591871>>> f.clean(['1', '2'])
    1860 [u'1', u'2']
     1872['1', '2']
    18611873>>> f.clean([1, '2'])
    1862 [u'1', u'2']
     1874['1', '2']
    18631875>>> f.clean((1, '2'))
    1864 [u'1', u'2']
     1876['1', '2']
    18651877>>> f.clean('hello')
    18661878Traceback (most recent call last):
    18671879...
     
    18751887...
    18761888ValidationError: [u'Select a valid choice. 3 is not one of the available choices.']
    18771889
     1890>>> f = MultipleChoiceField(choices=[(1, '1'), (2, '2')])
     1891>>> f.clean(['1'])
     1892[1]
     1893>>> f.clean(['1', '2'])
     1894[1, 2]
     1895>>> f.clean([1, '2'])
     1896[1, 2]
     1897
     1898>>> f = MultipleChoiceField(choices=[(u'1', '1'), (u'2', '2')])
     1899>>> f.clean(['1'])
     1900[u'1']
     1901>>> f.clean(['1', '2'])
     1902[u'1', u'2']
     1903>>> f.clean([1, '2'])
     1904[u'1', u'2']
     1905
    18781906# ComboField ##################################################################
    18791907
    18801908ComboField takes a list of fields that should be used to validate a value,
     
    25292557>>> f.errors
    25302558{}
    25312559>>> f.cleaned_data
    2532 {'composers': [u'J'], 'name': u'Yesterday'}
     2560{'composers': ['J'], 'name': u'Yesterday'}
    25332561>>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
    25342562>>> f.errors
    25352563{}
    25362564>>> f.cleaned_data
    2537 {'composers': [u'J', u'P'], 'name': u'Yesterday'}
     2565{'composers': ['J', 'P'], 'name': u'Yesterday'}
    25382566
    25392567Validation errors are HTML-escaped when output as HTML.
    25402568>>> class EscapingForm(Form):
  • tests/regressiontests/forms/regressions.py

     
    4949>>> UNITS = (('\xd0\xbc\xd0\xb5\xd1\x81.', '\xd0\xbc\xd0\xb5\xd1\x81.'), ('\xd1\x88\xd1\x82.', '\xd1\x88\xd1\x82.'))
    5050>>> f = ChoiceField(choices=UNITS)
    5151>>> f.clean(u'\u0448\u0442.')
     52'\xd1\x88\xd1\x82.'
     53>>> f.clean('\xd1\x88\xd1\x82.')
     54'\xd1\x88\xd1\x82.'
     55
     56>>> UNITS = ((u'\u043c\u0435\u0441.', u'\u043c\u0435\u0441.'), (u'\u0448\u0442.', u'\u0448\u0442.'))
     57>>> f = ChoiceField(choices=UNITS)
     58>>> f.clean(u'\u0448\u0442.')
    5259u'\u0448\u0442.'
    5360>>> f.clean('\xd1\x88\xd1\x82.')
    5461u'\u0448\u0442.'
Back to Top