约束参考

本模块中定义的类可以创建数据库约束。它们被添加到模型中 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

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

UniqueConstraint

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

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

fields

UniqueConstraint.fields

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

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

name

UniqueConstraint.name

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

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 上,可推迟的唯一约束被忽略,因为它们都不支持。

警告

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

include

UniqueConstraint.include
New in Django 3.2.

A list or tuple of the names of the fields to be included in the covering unique index as non-key columns. This allows index-only scans to be used for queries that select only included fields (include) and filter only by unique fields (fields).

例子:

UniqueConstraint(name='unique_booking', fields=['room', 'date'], include=['full_name'])

will allow filtering on room and date, also selecting full_name, while fetching data only from the index.

include is supported only on PostgreSQL.

Non-key columns have the same database restrictions as Index.include.

opclasses

UniqueConstraint.opclasses
New in Django 3.2.

The names of the PostgreSQL operator classes to use for this unique index. If you require a custom operator class, you must provide one for each field in the index.

例子:

UniqueConstraint(name='unique_username', fields=['username'], opclasses=['varchar_pattern_ops'])

creates a unique index on username using varchar_pattern_ops.

opclasses 对于 PostgreSQL 以外的数据库来说是被忽略的。