DJANGO: ModelChoiceField optgroup tag
An extension of @Stefan Manastirliu answer to use with django-categories. (Downside is that get_tree_data()
function below allows only one level) . In combination with javascript plugins like bootstrap multiselect you can get multi-select like
Models.py
from categories.models import CategoryBase
class SampleCategory(CategoryBase):
class Meta:
verbose_name_plural = 'sample categories'
class SampleProfile(models.Model):
categories = models.ManyToManyField('myapp.SampleCategory')
forms.py
from myapp.models import SampleCategory
def get_tree_data():
def rectree(toplevel):
children_list_of_tuples = list()
if toplevel.children.active():
for child in toplevel.children.active():
children_list_of_tuples.append(tuple((child.id,child.name)))
return children_list_of_tuples
data = list()
t = SampleCategory.objects.filter(active=True).filter(level=0)
for toplevel in t:
childrens = rectree(toplevel)
data.append(
tuple(
(
toplevel.name,
tuple(
childrens
)
)
)
)
return tuple(data)
class SampleProfileForm(forms.ModelForm):
categories = forms.MultipleChoiceField(choices=get_tree_data())
class Meta:
model = SampleProfile
Here's a good snippet:
Choice Field and Select Widget With Optional Optgroups: http://djangosnippets.org/snippets/200/
You don't need to create any custom field, Django already does the job, just pass the choices well formatted:
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
)