根据其他字段的值不要求字段

时间:2015-02-10 00:11:29

标签: django django-forms

我有一个Django ModelForm,我想要一个字段被视为有条件要求。我希望默认情况下需要它,但不需要,具体取决于另一个字段的值。我的模型看起来像是:

class MyModel(models.Model):
    foo = models.BooleanField()
    bar = models.CharField(choices=(('A', 'A'),('B', 'B'),('C', 'C')),)

我没有null=Trueblank=True,因此当我渲染表单时,它们都显示为“必需”,这就是我想要的。

但是,我的表单模板上有一些javascript,它会隐藏bar字段输入,具体取决于foo的输入值。在这种情况下,提交表单时,我不希望有任何关于bar的验证错误。

我试图在我的ModelForm的clean方法中实现这个逻辑,如下所示:

def clean(self):
    data = super(MyModelForm, self).clean()
    if data.get('foo') == True and 'bar' in self.errors:
        del self.errors['bar']
    return data

然而,这似乎仍然给我一个“这个字段不能空白”。错误。我注意到我的ModelForm也有一个_errors dict,但如果我尝试添加del self._errors['bar'],我最终会遇到异常。

我找到了一些与我想要的相反的方法(12),默认情况下不需要该字段,然后在某些情况下检查它是否需要在clean,但这不是我想要的。

我也尝试添加data['bar'] = " "作为解决方法但是我得到一个关于不选择其中一个选项的错误。理想情况下,我宁愿只能保存空字符串。

2 个答案:

答案 0 :(得分:1)

这里的问题是,除了调用表单的clean方法之外,form also calls post_clean on the form's instance。由于模型上的字段没有blank=True,因此在清理模型时会引发另一个错误并将其传递回表单。

要解决此问题,请在模型上设置blank=True。这会产生不必要的副作用,使字段在表单上显示为不需要。要在表单上创建所需的字段,只需在init中设置所需的标志:

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__( *args, **kwargs)
    self.fields['bar'].required = True

除了原始问题中的clean方法之外,这足以创建默认所需的条件必需字段,而不是基于另一个字段的值所需的字段。

答案 1 :(得分:0)

您可以覆盖_clean_fields方法以提供条件更改:

def _clean_fields(self):
    if self.data.get('foo', None) == True:
        self.fields['bar'].required = False
    super(MyForm, self)._clean_fields()