Django ModelForm foreign key group selection
I am creating a simple Q&C website Django 1.8
.
I want to create a select optgroup based on the foreing key (details below).
How can i do this?
college
class College(models.Model):
title = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
slug = models.SlugField(blank=True, max_length=100)
university = models.ForeignKey(to=University, related_name='college_list')
University
class University(models.Model):
title = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
slug = models.SlugField(unique=True, blank=True, max_length=100)
Question
class Question(models.Model):
title = models.CharField(max_length=150)
body = RedactorField(verbose_name=u'Vsebina')
slug = models.SlugField(unique=True, blank=True, max_length=100)
college = models.ForeignKey(to=College, default=1, related_name='questions')
QuestionForm
class CreateQuestionForm(ModelForm):
class Meta:
model = Question
fields = ['title', 'body', 'college']
Pattern (selection display)
{{ form.college }}
Current result
Necessary result
Thank!
source to share
I know this is an old version, but I found a solution to this problem of "displaying ModelChoiceField options assigned by ForeignKey to another model".
Django added the ability to provide nested optgroups to ChoiceField a few years ago. However, there is no automatic way to create nested variants like this from a queryset of nested model instances.
I was able to solve this using OrderedDict to organize the subgroups into groups and then set the selection for the .items () generator. It is important to understand that you are dealing with dynamic selection, as instances of the university and college model can change over time.
QuestionForm:
from collections import OrderedDict
from django.core.exceptions import ObjectDoesNotExist
class CreateQuestionForm(ModelForm):
"""
ModelForm which dynamically builds a nested set of choices for University and College
"""
class Meta:
model = Question
fields = ['title', 'body', 'college']
def __init__(self, *args, **kwargs):
super(CreateQuestionForm, self).__init__(*args, **kwargs) # Sets up the fields
university_college_choices_dict = OrderedDict() # Abused to sort into groups
for college in self.fields["college"].queryset.order_by("university__title", "college__title"):
choice_tuple = (college.pk, college.title)
try:
university_name = college.university.title
except (AttributeError, ObjectDoesNotExist):
university_name = False # Ends up in the generic ungrouped bin
try:
university_college_choices_dict[university_name].append(choice_tuple)
except KeyError:
university_college_choices_dict[university_name] = [choice_tuple]
self.fields["college"].choices = university_college_choices_dict.items() # MUST call .items() to extract the nested tuples
source to share