{{{
from django.forms.widgets import ChoiceWidget
w = ChoiceWidget(choices = [
("one", 1),
("two", 2), [
"italian", (
("uno", 1),
("due", 2)
)
]
])
}}}
now see how choices are grouped from optgroup:
{{{
import json
print(json.dumps(w.optgroups("name", "one"), indent = 4))
}}}
{{{
[
[
null,
[
{
"name": "name",
"value": "one",
"label": 1,
"selected": true,
"index": "0",
"attrs": {
"checked": true
},
"type": null,
"template_name": null
}
],
0
],
[
null,
[
{
"name": "name",
"value": "two",
"label": 2,
"selected": false,
"index": "1",
"attrs": {},
"type": null,
"template_name": null
}
],
1
],
[
"italian",
[
{
"name": "name",
"value": "uno",
"label": 1,
"selected": false,
"index": "2_0",
"attrs": {},
"type": null,
"template_name": null
},
{
"name": "name",
"value": "due",
"label": 2,
"selected": false,
"index": "2_1",
"attrs": {},
"type": null,
"template_name": null
}
],
2
]
]
}}}
this means that if choices are flats (no groups) you are getting a number
of groups that is the same of the number of choices, and in order to fix
this you need to use the grouping filters on the template in order to
regroup choices.
I think this is a bug, and flat choices should be grouped together as None
by optgroup method
thanks
--
Ticket URL: <https://code.djangoproject.com/ticket/29059>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* stage: Unreviewed => Accepted
Comment:
It might be fine -- can you offer a patch?
--
Ticket URL: <https://code.djangoproject.com/ticket/29059#comment:1>
* owner: nobody => Abhishek Gautam
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/29059#comment:2>
Comment (by Riccardo Di Virgilio):
Sure i'll do this in the next days.
Is it ok to provide just the function?
thanks!
--
Ticket URL: <https://code.djangoproject.com/ticket/29059#comment:3>
* needs_better_patch: 0 => 1
* has_patch: 0 => 1
Comment:
The suggested fix in [https://github.com/django/django/pull/9621 PR#9621]
breaks choice ordering: it will group all ungrouped choices at whatever
index the first ungrouped happens to have. This isn't something we should
impose. (We may want to present ungrouped default/common choices at the
beginning, some groups, and then some ungrouped "other" choices at the
end, for one example.)
How we might preserve current behaviour whilst allowing grouping of
ungrouped items seems tricky at best. It looks to me as if a better
approach would be to recommend using a custom widget and overriding
`optgroups` in order to gather ungrouped choices if that is what's
required.
I put this example on the PR. It's just an untested sketch but it should
demonstrate the idea:
{{{
def optgroups(self, name, value, attrs=None):
"""Override optgroups to group ungrouped choices at end."""
ret = []
none_choices = []
max_index = 0
for group_name, choices, index in super().optgroups(name, value,
attrs):
if group_name is None:
none_choices.append(choices)
else:
max_index = max(max_index, index)
ret.append((group_name, choices, index))
ret.append((None, none_choices, max_index +1))
return ret
}}}
As such I'd probably be inclined to close this as Won't Fix.
(We could document the suggestion, but "override methods to customise
behaviour" is just OOP.)
--
Ticket URL: <https://code.djangoproject.com/ticket/29059#comment:4>
* status: assigned => closed
* resolution: => wontfix
--
Ticket URL: <https://code.djangoproject.com/ticket/29059#comment:5>