假设我有一些人为的模型:
class Author(Model):
name = CharField()
class Book(Model):
title = CharField()
author = ForeignKey(Author)
让我们说我想使用ModelForm for Book:
class BookForm(ModelForm):
class Meta:
model = Book
到目前为止简单。但是我们也说我的数据库中有很多作者,而且我不想拥有这么长的多选字段。所以,我想在BookForm的ModelMultipleChoiceField作者字段上限制查询集。我们还要说在__init__
之前无法选择我想要的查询集,因为它依赖于要传递的参数。
这似乎可以解决问题:
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
当然,如果那个有效,我就不会在这里。这让我产生了一个AttributeError。 'BookForm'对象没有属性'author'。所以,我也试过这样的东西,我尝试覆盖ModelForm的默认字段,然后再设置它:
class BookForm(ModelForm):
author = ModelMultipleChoiceField(queryset=Author.objects.all())
class Meta:
model = Book
def __init__(self, letter):
choices = getChoices(letter)
self.author.queryset = choices
产生相同的结果。
任何人都知道如何做到这一点?
答案 0 :(得分:8)
表单对象没有其字段作为属性,您需要查看“fields”属性,这是一个字典:
self.fields['author'].queryset = choices
如果你想完全理解这里发生了什么,你可能会对this answer感兴趣 - 它是关于模型的,但是表单的工作方式类似。
答案 1 :(得分:7)
尽管卡尔对这些领域是正确的,但你也错过了超级级别的电话。我就是这样做的:
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