Code

Ticket #8103: 8103.2.diff

File 8103.2.diff, 3.3 KB (added by SmileyChris, 4 years ago)
Line 
1diff --git a/django/forms/widgets.py b/django/forms/widgets.py
2index cb12586..fc80732 100644
3--- a/django/forms/widgets.py
4+++ b/django/forms/widgets.py
5@@ -495,6 +495,8 @@ class CheckboxInput(Widget):
6         return bool(initial) != bool(data)
7 
8 class Select(Widget):
9+    allow_multiple_selected = False
10+
11     def __init__(self, attrs=None, choices=()):
12         super(Select, self).__init__(attrs)
13         # choices can be any iterable, but we may need to render this widget
14@@ -514,7 +516,13 @@ class Select(Widget):
15 
16     def render_option(self, selected_choices, option_value, option_label):
17         option_value = force_unicode(option_value)
18-        selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
19+        if option_value in selected_choices:
20+            selected_html = u' selected="selected"'
21+            if not self.allow_multiple_selected:
22+                # Only allow for a single selection.
23+                selected_choices.remove(option_value)
24+        else:
25+            selected_html = ''
26         return u'<option value="%s"%s>%s</option>' % (
27             escape(option_value), selected_html,
28             conditional_escape(force_unicode(option_label)))
29@@ -567,6 +575,8 @@ class NullBooleanSelect(Select):
30         return initial != data
31 
32 class SelectMultiple(Select):
33+    allow_multiple_selected = True
34+
35     def render(self, name, value, attrs=None, choices=()):
36         if value is None: value = []
37         final_attrs = self.build_attrs(attrs, name=name)
38diff --git a/tests/regressiontests/forms/widgets.py b/tests/regressiontests/forms/widgets.py
39index 10483a7..785b302 100644
40--- a/tests/regressiontests/forms/widgets.py
41+++ b/tests/regressiontests/forms/widgets.py
42@@ -463,6 +463,28 @@ over multiple times without getting consumed:
43 <option value="4">4</option>
44 </select>
45 
46+Only one option can be selected:
47+>>> print w.render('choices', 0, choices=(('0', 'extra'),))
48+<select name="choices">
49+<option value="0" selected="selected">0</option>
50+<option value="1">1</option>
51+<option value="2">2</option>
52+<option value="3">3</option>
53+<option value="4">4</option>
54+<option value="0">extra</option>
55+</select>
56+
57+Ensure that it still selects the first element next time round:
58+>>> print w.render('choices', 0, choices=(('0', 'extra'),))
59+<select name="choices">
60+<option value="0" selected="selected">0</option>
61+<option value="1">1</option>
62+<option value="2">2</option>
63+<option value="3">3</option>
64+<option value="4">4</option>
65+<option value="0">extra</option>
66+</select>
67+
68 Choices can be nested one level in order to create HTML optgroups:
69 >>> w.choices=(('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))))
70 >>> print w.render('nestchoice', None)
71@@ -674,6 +696,15 @@ True
72 >>> w._has_changed([1, 2], [u'1', u'3'])
73 True
74 
75+Multiple options (with the same value) can be selected:
76+>>> print w.render('choices', [1], choices=(('1', 'extra'),))
77+<select multiple="multiple" name="choices">
78+<option value="1" selected="selected">1</option>
79+<option value="2">2</option>
80+<option value="3">3</option>
81+<option value="1" selected="selected">extra</option>
82+</select>
83+
84 # Choices can be nested one level in order to create HTML optgroups:
85 >>> w.choices = (('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))))
86 >>> print w.render('nestchoice', None)