Ticket #8103: 8103.3.diff

File 8103.3.diff, 3.6 KB (added by charettes, 3 years ago)

updated to trunk and moved tests out of doctest

  • tests/regressiontests/forms/tests/widgets.py

     
    256256<option value="G">George</option>
    257257<option value="R">Ringo</option>
    258258</select>""")
     259       
     260        # Only one option can be selected, see #8103:
     261        self.assertEqual(w.render('choices', '0', choices=(('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))), """<select name="choices">
     262<option value="0" selected="selected">0</option>
     263<option value="1">1</option>
     264<option value="2">2</option>
     265<option value="3">3</option>
     266<option value="0">extra</option>
     267</select>""")
    259268
    260269        # The value is compared to its str():
    261270        self.assertEqual(w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')]), """<select name="num">
     
    440449<option value="R">Ringo</option>
    441450</select>""")
    442451
     452        # Multiple options (with the same value) can be selected, see #8103:
     453        self.assertEqual(w.render('choices', ['0'], choices=(('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))), """<select multiple="multiple" name="choices">
     454<option value="0" selected="selected">0</option>
     455<option value="1">1</option>
     456<option value="2">2</option>
     457<option value="3">3</option>
     458<option value="0" selected="selected">extra</option>
     459</select>""")
     460
    443461        # If multiple values are given, but some of them are not valid, the valid ones are selected:
    444462        self.assertEqual(w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles">
    445463<option value="J" selected="selected">John</option>
  • django/forms/widgets.py

     
    499499        return bool(initial) != bool(data)
    500500
    501501class Select(Widget):
     502    allow_multiple_selected = False
     503
    502504    def __init__(self, attrs=None, choices=()):
    503505        super(Select, self).__init__(attrs)
    504506        # choices can be any iterable, but we may need to render this widget
     
    518520
    519521    def render_option(self, selected_choices, option_value, option_label):
    520522        option_value = force_unicode(option_value)
    521         selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
     523        if option_value in selected_choices:
     524            selected_html = u' selected="selected"'
     525            if not self.allow_multiple_selected:
     526                # Only allow for a single selection.
     527                selected_choices.remove(option_value)
     528        else:
     529            selected_html = ''
    522530        return u'<option value="%s"%s>%s</option>' % (
    523531            escape(option_value), selected_html,
    524532            conditional_escape(force_unicode(option_label)))
    525533
    526534    def render_options(self, choices, selected_choices):
    527535        # Normalize to strings.
    528         selected_choices = set([force_unicode(v) for v in selected_choices])
     536        selected_choices = set(force_unicode(v) for v in selected_choices)
    529537        output = []
    530538        for option_value, option_label in chain(self.choices, choices):
    531539            if isinstance(option_label, (list, tuple)):
     
    571579        return initial != data
    572580
    573581class SelectMultiple(Select):
     582    allow_multiple_selected = True
     583
    574584    def render(self, name, value, attrs=None, choices=()):
    575585        if value is None: value = []
    576586        final_attrs = self.build_attrs(attrs, name=name)
Back to Top