- Author:
- JulieGoldberg
- Posted:
- April 8, 2015
- Language:
- Python
- Version:
- Not specified
- Score:
- 1 (after 1 ratings)
This class lets me have a model choice field that includes optgroups . Django has built-in support for optgroups if you explicitly set all the choices in a ChoiceField, but that doesn't help with ModelChoiceFields. Optgroups let you have nice-looking subscategories in huge dropdowns. They're even more useful if you're using something like selectize.js, because you have a ton of options.
If you inherit from GroupedModelChoiceField and override the optgroup_from_instance function, as in SampleChoiceField, you'll get a dropdown with your models with the expected optgroup tags in the html. Be sure to have your queryset first order by whatever you're displaying in optgroup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | from django import forms
class GroupedModelChoiceField(forms.ModelChoiceField):
def optgroup_from_instance(self, obj):
return ""
def __choice_from_instance__(self, obj):
return (obj.id, self.label_from_instance(obj))
def _get_choices(self):
if not self.queryset:
return []
all_choices = []
if self.empty_label:
current_optgroup = ""
current_optgroup_choices = [("", self.empty_label)]
else:
current_optgroup = self.optgroup_from_instance(self.queryset[0])
current_optgroup_choices = []
for item in self.queryset:
optgroup_from_instance = self.optgroup_from_instance(item)
if current_optgroup != optgroup_from_instance:
all_choices.append((current_optgroup, current_optgroup_choices))
current_optgroup_choices = []
current_optgroup = optgroup_from_instance
current_optgroup_choices.append(self.__choice_from_instance__(item))
all_choices.append((current_optgroup, current_optgroup_choices))
return all_choices
choices = property(_get_choices, forms.ChoiceField._set_choices)
# Example subclass
class ExampleChoiceField(GroupedModelChoiceField):
def optgroup_from_instance(self, obj):
return obj.group.name
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
This worked great. Thanks for sharing.
#
Great, thanks. One small improvement - replace lines 15-21 with this:
There's no need to have the empty choice in its own optgroup.
#
Please login first before commenting.