【问题标题】:Don't require field based on another field's value不需要基于另一个字段的值的字段
【发布时间】:2015-04-09 21:47:57
【问题描述】:

我有一个 Django ModelForm,我希望将一个字段视为有条件的必需字段。我希望默认情况下需要它,但根据另一个字段的值不需要它。我的模型看起来是这样的:

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

null=Trueblank=True 都没有,所以当我呈现我的表单时,两者都显示为“必需”,这正是我想要的。

但是,我的表单模板上有一些 javascript,根据 foo 的输入值隐藏了 bar 字段输入。在这种情况下,提交表单时,我不希望出现任何关于 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 字典,但如果我尝试添加 del self._errors['bar'] 我最终会遇到异常。

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

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

【问题讨论】:

  • if data.get('foo') and 'bar' in self.errors:
  • 谢谢,这是正确的样式。但是,这并不影响我在这里的问题。
  • 您是在编辑还是创建新对象?
  • 在这种特殊情况下,我正在创建一个新对象。

标签: django django-forms


【解决方案1】:

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

要解决此问题,请在模型上设置blank=True。这具有使该字段在表单上显示为不需要的副作用。要在表单上设置必填字段,只需在 init 中设置 required 标志:

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

这样,除了原题中的clean方法,就足以创建一个默认必填、非必填基于另一个字段的值的条件必填字段。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 很高兴知道这是一个可能的解决方案,但请注意,这是内部 Django API 的一部分(由领先的 _ 指出),您可能会遇到未记录的重大更改。
    猜你喜欢
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2010-11-13
    • 2015-01-21
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多