【问题标题】:How to Modify Choices of ModelMultipleChoiceField如何修改 ModelMultipleChoiceField 的选择
【发布时间】:2009-04-10 17:34:26
【问题描述】:

假设我有一些人为的模型:

class Author(Model):
   name = CharField()

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

假设我想为 Book 使用 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

产生相同的结果。

有人知道这是怎么做的吗?

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    虽然 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
    

    【讨论】:

    • 是的,我真正的问题区域有超类调用,但我在这个例子中跳过了它。
    • 很公平。我想我会把这个留给任何徘徊在这个问题中的人以供参考。
    • 当然。重要的是要看到 super().__init__() 需要在访问字段之前发生。
    【解决方案2】:

    表单对象没有字段作为属性,你需要查看“字段”属性,这是一个字典:

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

    如果您想完全了解这里发生了什么,您可能会对this answer 感兴趣 - 它与模型有关,但表单的工作原理类似。

    【讨论】:

    • 你的回答有点误导。正如它所说,ModelMultipleChoiceField 的 queryset 属性应该是一个查询集。它将用于验证。但是choices 指的是该字段的小部件,并表示实际呈现为选择
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    相关资源
    最近更新 更多