Django 2个字段之一不能为null

时间:2018-10-31 14:24:11

标签: python django python-3.x

我有一个与此模型相似的模型:

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    field1= models.IntegerField(null=True)
    field2 = models.IntegerField(null=True)

字段field1field2中的至少一个不能为null。如何在模型中验证?

3 个答案:

答案 0 :(得分:3)

Model.clean

通常在Model.clean [Django-doc]中编写这样的测试:

from django.core.exceptions import ValidationError

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    field1= models.IntegerField(null=True)
    field2 = models.IntegerField(null=True)

    def clean(self):
        super().clean()
        if self.field1 is None and self.field2 is None:
            raise ValidationError('Field1 or field2 are both None')

请注意,当您.save()建立模型时,默认情况下未验证此清洁方法 。通常仅由建立在此模型之上的ModelForm调用。您可以在.save()模型实例时修补.save()方法for example like here来强制执行验证,但是仍然存在通过ORM 规避的方法。

django-db-constraints(某些数据库不支持)

如果您的数据库支持它(例如MySQL simply ignores the CHECK constraints),则SQL提供一种添加额外约束的语法,而Django软件包django-db-constraints [GitHub]提供一些工具来指定此类约束,例如:

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    field1= models.IntegerField(null=True)
    field2 = models.IntegerField(null=True)

    class Meta:
        db_constraints = {
            'field_null': 'CHECK (field1 IS NOT NULL OR field2 IS NOT NULL)',
        }

答案 1 :(得分:1)

您可以使用Model.clean()方法:

def clean(self):
    if self.field1 is None and self.field2 is None:
        raise ValidationError(_('field1 or field2 should not be null'))

请参见https://docs.djangoproject.com/en/2.1/ref/models/instances/#django.db.models.Model.clean

答案 2 :(得分:0)

从Django 2.2开始,您可以在Django中使用built-in constraints功能。不需要第三方代码。