Loading django/forms/widgets.py +12 −2 Original line number Diff line number Diff line Loading @@ -499,6 +499,8 @@ class CheckboxInput(Widget): return bool(initial) != bool(data) class Select(Widget): allow_multiple_selected = False def __init__(self, attrs=None, choices=()): super(Select, self).__init__(attrs) # choices can be any iterable, but we may need to render this widget Loading @@ -518,14 +520,20 @@ class Select(Widget): def render_option(self, selected_choices, option_value, option_label): option_value = force_unicode(option_value) selected_html = (option_value in selected_choices) and u' selected="selected"' or '' if option_value in selected_choices: selected_html = u' selected="selected"' if not self.allow_multiple_selected: # Only allow for a single selection. selected_choices.remove(option_value) else: selected_html = '' return u'<option value="%s"%s>%s</option>' % ( escape(option_value), selected_html, conditional_escape(force_unicode(option_label))) def render_options(self, choices, selected_choices): # Normalize to strings. selected_choices = set([force_unicode(v) for v in selected_choices]) selected_choices = set(force_unicode(v) for v in selected_choices) output = [] for option_value, option_label in chain(self.choices, choices): if isinstance(option_label, (list, tuple)): Loading Loading @@ -571,6 +579,8 @@ class NullBooleanSelect(Select): return initial != data class SelectMultiple(Select): allow_multiple_selected = True def render(self, name, value, attrs=None, choices=()): if value is None: value = [] final_attrs = self.build_attrs(attrs, name=name) Loading tests/regressiontests/forms/tests/widgets.py +18 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,6 @@ from django.utils.translation import activate, deactivate from django.utils.unittest import TestCase class FormsWidgetTestCase(TestCase): # Each Widget class corresponds to an HTML form widget. A Widget knows how to # render itself, given a field name and some data. Widgets don't perform Loading Loading @@ -255,6 +254,15 @@ class FormsWidgetTestCase(TestCase): <option value="P">Paul</option> <option value="G">George</option> <option value="R">Ringo</option> </select>""") # Only one option can be selected, see #8103: self.assertEqual(w.render('choices', '0', choices=(('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))), """<select name="choices"> <option value="0" selected="selected">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="0">extra</option> </select>""") # The value is compared to its str(): Loading Loading @@ -438,6 +446,15 @@ class FormsWidgetTestCase(TestCase): <option value="P">Paul</option> <option value="G">George</option> <option value="R">Ringo</option> </select>""") # Multiple options (with the same value) can be selected, see #8103: self.assertEqual(w.render('choices', ['0'], choices=(('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))), """<select multiple="multiple" name="choices"> <option value="0" selected="selected">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="0" selected="selected">extra</option> </select>""") # If multiple values are given, but some of them are not valid, the valid ones are selected: Loading Loading
django/forms/widgets.py +12 −2 Original line number Diff line number Diff line Loading @@ -499,6 +499,8 @@ class CheckboxInput(Widget): return bool(initial) != bool(data) class Select(Widget): allow_multiple_selected = False def __init__(self, attrs=None, choices=()): super(Select, self).__init__(attrs) # choices can be any iterable, but we may need to render this widget Loading @@ -518,14 +520,20 @@ class Select(Widget): def render_option(self, selected_choices, option_value, option_label): option_value = force_unicode(option_value) selected_html = (option_value in selected_choices) and u' selected="selected"' or '' if option_value in selected_choices: selected_html = u' selected="selected"' if not self.allow_multiple_selected: # Only allow for a single selection. selected_choices.remove(option_value) else: selected_html = '' return u'<option value="%s"%s>%s</option>' % ( escape(option_value), selected_html, conditional_escape(force_unicode(option_label))) def render_options(self, choices, selected_choices): # Normalize to strings. selected_choices = set([force_unicode(v) for v in selected_choices]) selected_choices = set(force_unicode(v) for v in selected_choices) output = [] for option_value, option_label in chain(self.choices, choices): if isinstance(option_label, (list, tuple)): Loading Loading @@ -571,6 +579,8 @@ class NullBooleanSelect(Select): return initial != data class SelectMultiple(Select): allow_multiple_selected = True def render(self, name, value, attrs=None, choices=()): if value is None: value = [] final_attrs = self.build_attrs(attrs, name=name) Loading
tests/regressiontests/forms/tests/widgets.py +18 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,6 @@ from django.utils.translation import activate, deactivate from django.utils.unittest import TestCase class FormsWidgetTestCase(TestCase): # Each Widget class corresponds to an HTML form widget. A Widget knows how to # render itself, given a field name and some data. Widgets don't perform Loading Loading @@ -255,6 +254,15 @@ class FormsWidgetTestCase(TestCase): <option value="P">Paul</option> <option value="G">George</option> <option value="R">Ringo</option> </select>""") # Only one option can be selected, see #8103: self.assertEqual(w.render('choices', '0', choices=(('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))), """<select name="choices"> <option value="0" selected="selected">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="0">extra</option> </select>""") # The value is compared to its str(): Loading Loading @@ -438,6 +446,15 @@ class FormsWidgetTestCase(TestCase): <option value="P">Paul</option> <option value="G">George</option> <option value="R">Ringo</option> </select>""") # Multiple options (with the same value) can be selected, see #8103: self.assertEqual(w.render('choices', ['0'], choices=(('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))), """<select multiple="multiple" name="choices"> <option value="0" selected="selected">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="0" selected="selected">extra</option> </select>""") # If multiple values are given, but some of them are not valid, the valid ones are selected: Loading