Django ModelForm中动态修改字段选项

3

我有一个模型上的字段,如下:

class MyModel(models.Model):
    status_field = models.NullBooleanField(blank=False,
                                          verbose_name="Status",
                                          choices=((True, 'Approved'),
                                                   (False, 'Denied'),
                                                   (None, 'Pending')))

我有一个关于这个模型的ModelForm。在这个ModelForm中,我想要有条件地动态移除其中一个选项。我目前正在尝试:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)


        if self.instance and self.instance.status_field is not None:
            self.fields['status_field'].choices.remove((None, 'Pending'))
            print self.fields['status_field'].choices

我可以从打印语句中看出该选择确实被删除了。但是,当表单被渲染时,该字段的小部件仍然包括我删除的选项,我一定漏掉了些什么。
实际上,我的目标是防止该字段在提供了值之后变为None/null。为了方便用户,我想只需在下拉菜单中删除此选项即可。
感谢您的帮助!
1个回答

13

然后,表单被初始化,choices 属性被从字段复制到字段的小部件中。 因此,您也必须从小部件中删除选择:

if self.instance and self.instance.status_field is not None:
    new_choices = list(self.fields['status_field'].choices)
    new_choices.remove((None, 'Pending'))
    self.fields['status_field'].choices = new_choices
    self.fields['status_field'].widget.choices = new_choices

谢谢,我明白了,明天回去继续工作时我会试一下的。 - Joseph
我将保留这个答案的“正确性”,因为我认为它确实回答了我提出的具体问题。然而,它并不是解决我试图解决的实际问题的好方法。一旦选择被移除,即使您在status_field为None的实例上使用表单,它也会消失。 - Joseph
1
我必须进行预测,抱歉。为了解决这个问题,您需要复制原始的“choices”并从该副本中删除“待定”状态。请参见更新后的答案。 - catavaran
不行,这也不起作用 :-( 我忘了加上 list() 调用来复制原始的 choices。看另一个更新。 - catavaran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接