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')
请注意,在创建模型时,默认情况下会验证此清理方法.它通常只被建立在这个模型之上的ModelForm
调用.您可以在.save()
模型实例时修补.save()
方法for example like here以强制验证,但仍然有办法通过ORM实现这一点.
django-db-constraints
(not supported by some databases)
如果您的数据库支持它(例如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)',
}
Update: Django constraint framework
Since django-2.2, you can make use of the Django constraint framework [Django-doc]. With this framework, you can specify database constraints that are, given the database supports this, validated at database side. You thus can check if at least one of the two fields is not NULL
with a CheckConstraint
[Django-doc]:
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:
constraints = [
models.CheckConstraint(
check=Q(field1__isnull=False) | Q(field2__isnull=False),
name='not_both_null'
)
]