约束参考

本模块中定义的类可以创建数据库约束。它们被添加到模型中 Meta.constraints 选项中。

引用内置约束

约束是在 django.db.models.constraint 中定义的,但为了方便,它们被导入到 django.db.models 中。标准的惯例是使用 from django.db import models 作为 models.<Foo>Constraint

抽象基类中的约束

你必须始终为约束指定一个唯一的名称。因此,你通常不能在抽象基类上指定一个约束,因为 Meta.craces 选项是由子类继承的,每次的属性值(包括 name)都完全相同。为了解决名称碰撞的问题,名称的一部分可能包含 '%(app_label)s''%(class)s',它们分别被具体模型的小写应用标签和类名所代替。例如 CheckConstraint(check=Q(age__gte=18),name='%(app_label)s_%(class)s_is_adult')

约束的验证

一般来说,在 full_clean() 期间,约束条件 不会被 检查,也不会引起 ValidationError。而是在 save() 时,你会得到一个数据库完整性错误。没有 conditionUniqueConstraint (即非部分唯一约束)在这方面是不同的,它们利用了现有的 validate_unique() 逻辑,从而实现了两阶段验证。除了在 save() 上出现 IntegrityError 外,在模型验证过程中,当 UniqueConstraint 被违反时,ValidationError 也会被引发。

CheckConstraint

class CheckConstraint(*, check, name)

在数据库中创建一个检查约束

check

CheckConstraint.check

一个 Q 对象或布尔值 Expression,它指定了你要强制约束的检查。

例如,CheckConstraint(check=Q(age__gte=18), name='age_gte_18') 确保年龄字段永远不小于 18。

Changed in Django 3.1:

增加了对布尔 Expression 的支持。

name

CheckConstraint.name

约束的名称。你必须始终为约束指定一个唯一的名称。

Changed in Django 3.0:

增加了 '%(app_label)s''%(class)s' 插值。

UniqueConstraint

class UniqueConstraint(*, fields, name, condition=None, deferrable=None)

在数据库中创建一个唯一约束。

fields

UniqueConstraint.fields

一个字段名的列表,它指定了你要强制约束的唯一列集。

例如,UniqueConstraint(field=['room', 'date'], name='unique_booking') 确保每个房间在每个日期只能被预订一次。

name

UniqueConstraint.name

约束的名称。你必须始终为约束指定一个唯一的名称。

Changed in Django 3.0:

增加了 '%(app_label)s''%(class)s' 插值。

condition

UniqueConstraint.condition

一个 Q 对象,用于指定你想要强制执行的约束条件。

例子:

UniqueConstraint(fields=['user'], condition=Q(status='DRAFT'), name='unique_draft_user')

确保每个用户只有一份草稿。

这些条件与 Index.condition 具有相同的数据库限制。

deferrable

UniqueConstraint.deferrable
New in Django 3.1.

设置该参数,可创建一个可推迟的唯一约束。接受的值是 Deferrable.DEFERREDDeferrable.IMMEDIATE。例如:

from django.db.models import Deferrable, UniqueConstraint

UniqueConstraint(
    name='unique_order',
    fields=['order'],
    deferrable=Deferrable.DEFERRED,
)

默认情况下,约束条件是不推迟的。推迟的约束条件在事务结束前不会被强制执行。即时约束将在每条命令后立即执行。

MySQL,MariaDB 和 SQLite。

在 MySQL、MariaDB 和 SQLite 上,可推迟的唯一约束被忽略,因为它们都不支持。

警告

推迟的唯一约束可能导致 性能惩罚