Search code examples
djangoformsmodels

Django Form Fields based on Model Choices


I want to offer form fields based on model choices. So, if in my models:

COLORS = (
    ('BLA', 'Black'),
    ('WHI', 'White'),
    ('RED', 'Red'),
    ('BLU', 'Blue'),
)

YEAR_CHOICES = []
for r in range(1980, (datetime.datetime.now().year+1)):
    YEAR_CHOICES.append((r,r))

class Thing(models.Model):
    stuff = models.ForeignKey(Stuff)
    color = models.CharField(max_length=3, choices=COLORS)
    year = models.IntegerField(('year'), max_length=4, choices=YEAR_CHOICES, default=datetime.datetime.now().year)

I want to create two form fields, one whose <select> options are YEAR_CHOICES and one whose options are COLORS. Can you do this using ModelChoiceField? Re-defining choices in my forms.py does not seem very DRY.. Otherwise, how would you solve this issue?

Something like this is what I had envisioned, but it does not work:

class BrowseForm(forms.Form):
    stuff = forms.ModelChoiceField(queryset=Stuff.objects.all())
    color = forms.ModelChoiceField(queryset=Thing.color.choices())
    year = forms.ModelChoiceField(queryset=Thing.year.choices())

Solution

  • from the docs (here)

    you can use the select widget and specify choices. In your case

    color = forms.CharField(max_length=20, widget=forms.Select(choices=COLORS))

    However, since you've already defined color with choices you in fact do not need to do anything (other than set the meta of BrowseForm to Thing) to get this to work. It will default to the behavior you want.