Let's say I have some contrived models:
class Author(Model):
name = CharField()
class Book(Model):
title = CharField()
author = ForeignKey(Author)
And let's say I want to use a ModelForm for Book:
class BookForm(ModelForm):
class Meta:
model = Book
Simple so far. But let's also say that I have a ton of Authors in my database, and I don't want to have such a long multiple choice field. So, I'd like is to restrict the queryset on the BookForm's ModelMultipleChoiceField author field. Let's also say that the queryset I want can't be chosen until __init__
, because it relies on an argument to be passed.
This seems like it might do the trick:
class BookForm(ModelForm):
class Meta:
model = Book
def __init__(self, letter):
# returns the queryset based on the letter
choices = getChoices(letter)
self.author.queryset = choices
Of course, if that just worked I wouldn't be here. That gets me an AttributeError. 'BookForm' object has no attribute 'author'. So, I also tried something like this, where I try to override the ModelForm's default field and then set it later:
class BookForm(ModelForm):
author = ModelMultipleChoiceField(queryset=Author.objects.all())
class Meta:
model = Book
def __init__(self, letter):
choices = getChoices(letter)
self.author.queryset = choices
Which produces the same result.
Anyone know how this is intended to be done?
Although Carl is correct about the fields, you're also missing a super class call. This is how I do it:
class BookForm(ModelForm):
author = ModelMultipleChoiceField(queryset=Author.objects.all())
class Meta:
model = Book
def __init__(self, *args, **kwargs):
letter = kwargs.pop('letter')
super(BookForm, self).__init__(*args, **kwargs)
choices = getChoices(letter)
self.fields['author'].queryset = choices
Form objects don't have their fields as attributes, you need to look in the "fields" attribute, which is a dictionary:
self.fields['author'].queryset = choices
If you want to fully understand what's going on here, you might be interested in this answer - it's about Models, but Forms work similarly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With