2009-04-10 69 views
5

的选择比方说,我有一些做作型号:如何修改ModelMultipleChoiceField

class Author(Model): 
    name = CharField() 

class Book(Model): 
    title = CharField() 
    author = ForeignKey(Author) 

而且我们说,我想使用的ModelForm的书:

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'对象没有属性'作者'。所以,我也尝试过这样的事情,在这里我试图重写的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 

将会产生相同的结果。

任何人都知道这是如何完成的?

回答

8

表单对象没有自己的领域属性,则需要在“域”属性,这是一本字典看:

self.fields['author'].queryset = choices 

如果你想完全明白是怎么回事,你可能对this answer感兴趣 - 它是关于Models的,但Forms的工作方式相似。

7

尽管Carl对这些字段是正确的,但您也错过了超类调用。我是这样做的:

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 
+0

是的,我真正的问题领域有超类调用,但我跳过了这个例子。 – Brian 2009-04-10 18:38:05