有条件地只需要 Django 模型表单中的一个字段

Posted

技术标签:

【中文标题】有条件地只需要 Django 模型表单中的一个字段【英文标题】:Conditionally Require Only One Field In Django Model Form 【发布时间】:2011-01-10 06:03:54 【问题描述】:

是否根据是否填写了同一表单中的另一个字段来使一个字段有条件地需要?

If field1 has no data, but field2 does
    form is valid.

If field1 has no data and field2 has no data
    form is invalid

不寻找任何 javascript 解决方案。我觉得应该用 django 表单来解决它,但不太确定如何最好地解决它。

【问题讨论】:

【参考方案1】:

如果您知道验证将应用于此类的所有对象,您也可以使用模型来执行此操作。要在表单级别使用以下内容,请使用cleaned_data。这是 Django 文档中使用 ValidationError 的示例:

class Article(models.Model):

    status = models.CharField(max_length=75, blank=False, null=False)
    pub_date = models.CharField(max_length=75, blank=False, null=False)

    def clean(self):
        # Don't allow draft entries to have a pub_date.
        if self.status == 'draft' and self.pub_date is not None:
            raise ValidationError('Draft entries may not have a publication date.')
        # Set the pub_date for published items if it hasn't been set already.
        if self.status == 'published' and self.pub_date is None:
            self.pub_date = datetime.date.today()

参考:Model Instance Clean,Django Validators

这是一个表单示例:

class SimpleForm(forms.ModelForm):

    def clean(self):
        cleaned_data = super(SimpleForm, self).clean()  # Get the cleaned data from default clean, returns cleaned_data
        field1 = cleaned_data.get("field1")
        field2 = cleaned_data.get("field2"),

        if not field1 and not field2:
            raise forms.ValidationError('Please fill in both fields.')

        return cleaned_data

参考:Form & Field Validation

【讨论】:

【参考方案2】:

覆盖 .clean(self) 方法,检查 self.cleaned_data 并引发 ValidationError

https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

【讨论】:

注意:如果为 Django CMS 插件执行此操作,请确保在插件的 models.py 定义中覆盖 clean(self) 方法,而不是在 forms.py 中。【参考方案3】:

条件必填字段的最佳解决方案是覆盖表单的 clean 方法并在条件下弹出错误。例如:

clean(self):
    if self.cleaned_data.get(some_field) == 1:
        self.errors.pop(other_field, None)

【讨论】:

以上是关于有条件地只需要 Django 模型表单中的一个字段的主要内容,如果未能解决你的问题,请参考以下文章

有条件地需要 Django 表单字段

在 Django 中,为啥模型中的 blank=True 不会使表单字段不是强制性的?

Django 向导表单中的条件表单字段

Django 访问不属于表单的字段

Django Crispy 表单根据需要设置模型字段

具有来自两个不同模型的字段的 Django 表单