我有一个Django ModelForm,我想要一个字段被视为有条件要求。我希望默认情况下需要它,但不需要,具体取决于另一个字段的值。我的模型看起来像是:
class MyModel(models.Model):
foo = models.BooleanField()
bar = models.CharField(choices=(('A', 'A'),('B', 'B'),('C', 'C')),)
我没有null=True
或blank=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']
,我最终会遇到异常。
我找到了一些与我想要的相反的方法(1,2),默认情况下不需要该字段,然后在某些情况下检查它是否需要在clean
,但这不是我想要的。
我也尝试添加data['bar'] = " "
作为解决方法但是我得到一个关于不选择其中一个选项的错误。理想情况下,我宁愿只能保存空字符串。
答案 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()