我有一个类似的模型:

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相关问答推荐

使用正确的数据类型时,使用 Cerberus 验证 JSON 架构会引发错误

总结基于条件的值,如果不匹配则保留当前值

机器学习实验笔记本的工作区 url

列表中的重复数字与列表理解

如何准确测定cv2的结果.在BW/黑白图像中查找对象?

聚合(aggregate)为最多包含两个元素的列表

在“with”语句中调用构造函数

pip search 和 pip install 出错

没有找到 Python;不带参数运行以从 Microsoft Store 安装,或从“设置”中禁用此快捷方式

ImportError:无法从“distutils”(/usr/lib/python3.8/distutils/__init__.py)导入名称“sysconfig”

python3:字节与字节数组,并转换为字符串和从字符串转换

asyncio.create_task() 做什么?

Python 多行 with 语句

从 __future__ 导入注释

无法在仅 tensorflow CPU 安装上加载动态库“cudart64_101.dll”

random.choices() 和 random.sample() 函数有什么区别?

替换 tensorflow v2 的占位符

如何安装 libpq-fe.h?

Python3.7:加载共享库时出错:libpython3.7m.so.1.0

简单的 get/post 请求在 python 3 中被阻止,但在 python 2 中没有