约束参考

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

引用内置约束

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

抽象基类中的约束

你必须始终为约束指定一个唯一的名称。因此,通常不能在抽象基类上指定约束,因为 Meta.constraints 选项会被子类继承,每次属性的值(包括 name)完全相同。为了避免名称冲突,名称的一部分可以包含 '%(app_label)s''%(class)s',它们分别被具体模型的小写应用标签和类名替换。例如 CheckConstraint(condition=Q(age__gte=18), name='%(app_label)s_%(class)s_is_adult')

约束的验证

约束在 模型验证 过程中进行检查。

BaseConstraint

class BaseConstraint(*name, violation_error_code=None, violation_error_message=None)[source]

所有约束的基类。子类必须实现 constraint_sql(), create_sql(), remove_sql()validate() 方法。

Deprecated since version 5.0: 不再支持传递位置参数。

所有约束都有以下共同的参数:

name

BaseConstraint.name

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

violation_error_code

BaseConstraint.violation_error_code

模型验证 过程中引发 ValidationError 时使用的错误代码。默认值为 None

violation_error_message

BaseConstraint.violation_error_message

模型验证 过程中引发 ValidationError 时使用的错误消息。默认为 "违反了约束“%(name)s”"

validate()

BaseConstraint.validate(model, instance, exclude=None, using=DEFAULT_DB_ALIAS)[source]

验证在 model 上定义的约束是否在 instance 上被遵守。这将在数据库上执行一个查询,以确保该约束被遵守。如果需要使用 exclude 列表中的字段来验证约束,则会忽略该约束。

如果违反了约束,则引发 ValidationError

这个方法必须由子类来实现。

CheckConstraint

class CheckConstraint(*, condition, name, violation_error_code=None, violation_error_message=None)[source]

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

condition

CheckConstraint.condition

一个 Q 对象或布尔 Expression,用于指定你希望约束强制执行的条件检查。

例如,CheckConstraint(condition=Q(age__gte=18), name='age_gte_18') 确保 age 字段永远不会小于 18。

表达式顺序

Q 参数的顺序未必会被保留,但 Q 表达式本身的顺序会被保留。这对于一些为了性能原因而保留检查约束表达式顺序的数据库可能很重要。例如,如果顺序很重要,请使用以下格式:

CheckConstraint(
    condition=Q(age__gte=18) & Q(expensive_check=condition),
    name="age_gte_18_and_others",
)

Oracle < 23c

在 Oracle < 23c 上,具有可空字段的检查必须包括允许 NULL 值的条件,以便 validate() 的行为与检查约束验证相同。例如,如果 age 是一个可空字段:

CheckConstraint(condition=Q(age__gte=18) | Q(age__isnull=True), name="age_gte_18")

Deprecated since version 5.1: check 属性已弃用,推荐使用 condition

UniqueConstraint

class UniqueConstraint(*expressions, fields=(), name=None, condition=None, deferrable=None, include=None, opclasses=(), nulls_distinct=None, violation_error_code=None, violation_error_message=None)[source]

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

expressions

UniqueConstraint.expressions

位置参数 *expressions 允许在表达式和数据库函数上创建功能性唯一约束。

例子:

UniqueConstraint(Lower("name").desc(), "category", name="unique_lower_name_category")

在降序中的 name 字段的小写值和默认升序中的 category 字段上创建了一个唯一约束。

功能性唯一约束具有与 Index.expressions 相同的数据库限制。

fields

UniqueConstraint.fields

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

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

condition

UniqueConstraint.condition

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

例子:

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

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

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

deferrable

UniqueConstraint.deferrable

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

from django.db.models import Deferrable, UniqueConstraint

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

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

MySQL,MariaDB 和 SQLite。

Deferrable unique constraints are ignored on MySQL, MariaDB, and SQLite as they do not support them.

Warning

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

include

UniqueConstraint.include

一个包含在覆盖的唯一索引中的字段名称的列表或元组,作为非键列。这允许只用索引扫描,用于只选择包含的字段( include )和只过滤唯一字段( fields )的查询。

例子:

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

将允许对 roomdate 进行过滤,也可以选择 full_name,同时只从索引中获取数据。

非主键列的唯一约束在除了 PostgreSQL 之外的数据库中被忽略。

非关键列具有与 Index.include 相同的数据库限制。

opclasses

UniqueConstraint.opclasses

用于此唯一索引的 PostgreSQL 操作符类别 的名称。如果需要自定义操作符类别,必须为索引中的每个字段提供一个。

例子:

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

使用 varchar_pattern_opsusername 上创建了一个唯一索引。

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

nulls_distinct

UniqueConstraint.nulls_distinct

是否应该将包含 NULL 值的行视为彼此不同,而不是唯一约束覆盖它们。默认值是 None,它使用数据库默认值,在大多数后端上为 True

例子:

UniqueConstraint(name="ordering", fields=["ordering"], nulls_distinct=False)

创建一个唯一约束,只允许一行在 ordering 列中存储一个 NULL 值。

非主键列的唯一约束在除了 PostgreSQL 15+ 之外的数据库中被忽略。

violation_error_code

UniqueConstraint.violation_error_code

The error code used when a ValidationError is raised during model validation.

Defaults to BaseConstraint.violation_error_code, when either UniqueConstraint.condition is set or UniqueConstraint.fields is not set.

If UniqueConstraint.fields is set without a UniqueConstraint.condition, defaults to the Meta.unique_together error code when there are multiple fields, and to the Field.unique error code when there is a single field.

Changed in Django 5.2:

In older versions, the provided UniqueConstraint.violation_error_code was not used when UniqueConstraint.fields was set without a UniqueConstraint.condition.

violation_error_message

UniqueConstraint.violation_error_message

The error message used when a ValidationError is raised during model validation.

Defaults to BaseConstraint.violation_error_message, when either UniqueConstraint.condition is set or UniqueConstraint.fields is not set.

If UniqueConstraint.fields is set without a UniqueConstraint.condition, defaults to the Meta.unique_together error message when there are multiple fields, and to the Field.unique error message when there is a single field.

Changed in Django 5.2:

In older versions, the provided UniqueConstraint.violation_error_message was not used when UniqueConstraint.fields was set without a UniqueConstraint.condition.