summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2017-05-03 07:21:44 -0400
committerGitHub <noreply@github.com>2017-05-03 07:21:44 -0400
commitd302e2c09c281e6b1e187f704f656e5e79e69246 (patch)
treeb48c0e196175ae368268b5605a29ad79c99764f0
parent13cd5b067054f40c6ca723c97fff56c510c04295 (diff)
Fixed #28157 -- Fixed choice ordering in form fields with grouped and non-grouped options.
Regression in b52c73008a9d67e9ddbb841872dc15cdd3d6ee01.
-rw-r--r--django/forms/widgets.py14
-rw-r--r--docs/releases/1.11.1.txt3
-rw-r--r--tests/forms_tests/widget_tests/test_select.py96
3 files changed, 76 insertions, 37 deletions
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 2feded85c7..37c11f1241 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -547,25 +547,23 @@ class ChoiceWidget(Widget):
def optgroups(self, name, value, attrs=None):
"""Return a list of optgroups for this widget."""
- default = (None, [], 0)
- groups = [default]
+ groups = []
has_selected = False
- for option_value, option_label in chain(self.choices):
+ for index, (option_value, option_label) in enumerate(chain(self.choices)):
if option_value is None:
option_value = ''
+ subgroup = []
if isinstance(option_label, (list, tuple)):
- index = groups[-1][2] + 1
+ group_name = option_value
subindex = 0
- subgroup = []
- groups.append((option_value, subgroup, index))
choices = option_label
else:
- index = len(default[1])
- subgroup = default[1]
+ group_name = None
subindex = None
choices = [(option_value, option_label)]
+ groups.append((group_name, subgroup, index))
for subvalue, sublabel in choices:
selected = (
diff --git a/docs/releases/1.11.1.txt b/docs/releases/1.11.1.txt
index 64394aa755..9a9d96bf46 100644
--- a/docs/releases/1.11.1.txt
+++ b/docs/releases/1.11.1.txt
@@ -78,3 +78,6 @@ Bugfixes
* Prevented migrations from dropping database indexes from ``Meta.indexes``
when changing ``Field.db_index`` to ``False`` (:ticket:`28052`).
+
+* Fixed a regression in choice ordering in form fields with grouped and
+ non-grouped options (:ticket:`28157`).
diff --git a/tests/forms_tests/widget_tests/test_select.py b/tests/forms_tests/widget_tests/test_select.py
index 047d007564..a5201e96e8 100644
--- a/tests/forms_tests/widget_tests/test_select.py
+++ b/tests/forms_tests/widget_tests/test_select.py
@@ -280,35 +280,73 @@ class SelectTest(WidgetTest):
groups = list(self.widget(choices=choices).optgroups(
'name', ['vhs'], attrs={'class': 'super'},
))
- self.assertEqual(len(groups), 3)
- self.assertEqual(groups[0][0], None)
- self.assertEqual(groups[0][2], 0)
- self.assertEqual(len(groups[0][1]), 1)
- options = groups[0][1]
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'unknown')
- self.assertEqual(options[0]['label'], 'Unknown')
- self.assertEqual(options[0]['index'], '0')
- self.assertEqual(options[0]['selected'], False)
- self.assertEqual(groups[1][0], 'Audio')
- self.assertEqual(groups[1][2], 1)
- self.assertEqual(len(groups[1][1]), 2)
- options = groups[1][1]
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'vinyl')
- self.assertEqual(options[0]['label'], 'Vinyl')
- self.assertEqual(options[0]['index'], '1_0')
- self.assertEqual(options[1]['index'], '1_1')
- self.assertEqual(groups[2][0], 'Video')
- self.assertEqual(groups[2][2], 2)
- self.assertEqual(len(groups[2][1]), 2)
- options = groups[2][1]
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'vhs')
- self.assertEqual(options[0]['label'], 'VHS Tape')
- self.assertEqual(options[0]['index'], '2_0')
- self.assertEqual(options[0]['selected'], True)
- self.assertEqual(options[1]['index'], '2_1')
+ audio, video, unknown = groups
+ label, options, index = audio
+ self.assertEqual(label, 'Audio')
+ self.assertEqual(
+ options,
+ [{
+ 'value': 'vinyl',
+ 'type': 'select',
+ 'attrs': {},
+ 'index': '0_0',
+ 'label': 'Vinyl',
+ 'template_name': 'django/forms/widgets/select_option.html',
+ 'name': 'name',
+ 'selected': False,
+ }, {
+ 'value': 'cd',
+ 'type': 'select',
+ 'attrs': {},
+ 'index': '0_1',
+ 'label': 'CD',
+ 'template_name': 'django/forms/widgets/select_option.html',
+ 'name': 'name',
+ 'selected': False,
+ }]
+ )
+ self.assertEqual(index, 0)
+ label, options, index = video
+ self.assertEqual(label, 'Video')
+ self.assertEqual(
+ options,
+ [{
+ 'value': 'vhs',
+ 'template_name': 'django/forms/widgets/select_option.html',
+ 'label': 'VHS Tape',
+ 'attrs': {'selected': True},
+ 'index': '1_0',
+ 'name': 'name',
+ 'selected': True,
+ 'type': 'select',
+ }, {
+ 'value': 'dvd',
+ 'template_name': 'django/forms/widgets/select_option.html',
+ 'label': 'DVD',
+ 'attrs': {},
+ 'index': '1_1',
+ 'name': 'name',
+ 'selected': False,
+ 'type': 'select',
+ }]
+ )
+ self.assertEqual(index, 1)
+ label, options, index = unknown
+ self.assertEqual(label, None)
+ self.assertEqual(
+ options,
+ [{
+ 'value': 'unknown',
+ 'selected': False,
+ 'template_name': 'django/forms/widgets/select_option.html',
+ 'label': 'Unknown',
+ 'attrs': {},
+ 'index': '2',
+ 'name': 'name',
+ 'type': 'select',
+ }]
+ )
+ self.assertEqual(index, 2)
def test_deepcopy(self):
"""