我有一个类似的模型:

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中至少有一个不能为空.我如何在模型中验证它?

推荐答案

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 , 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'
            )
        ]

Python-3.x相关问答推荐

如何匹配字母,数字,短划线,逗号,但不是如果没有数字和字母?

如何绘制交叉验证的AUROC并找到最佳阈值?

比较和排序 DataFrame 两列中的值并在 python 中的同一行中排序

拆分列表的元素并将拆分后的元素包含到列表中

转换Pandas 数据框 - 添加行

在 python f-string 中使用 \u

pytorch 中 mps 设备的 manual_seed

使用gekko python的混合整数非线性规划

!date 的命令无法从 jupyter notebook 运行

DynamoDB - boto3 - batch_write_item:提供的关键元素与架构不匹配

为什么 return node.next 会返回整个链表?

Python.在循环中填充字典的问题

RGB 图像中最主要的 colored颜色 - OpenCV / NumPy / Python

PyQt:退出时没有错误消息(回溯)

Python3四舍五入到最接近的偶数

通过多个键对字典列表进行分组和聚合

判断 dict.items() 中的成员资格的时间复杂度是多少?

Python 2 与 Python 3 - urllib 格式

如何创建一个永远在其上运行滚动协程的事件循环?

__iter__ 和 __getitem__ 有什么区别?