约束参考¶
此模块中定义的类创建数据库约束。它们添加到模型的 Meta.constraints
选项中。
引用内置约束
约束定义在 django.db.models.constraints
中,但为了方便起见,它们被导入到 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()
方法。自 5.0 版本起已弃用: 传递位置参数的支持已被弃用。
所有约束都有一些共同的参数
name
¶
- BaseConstraint.name¶
约束的名称。你必须始终为约束指定一个唯一名称。
violation_error_code
¶
- BaseConstraint.violation_error_code¶
在 模型验证期间引发 ValidationError
时使用的错误代码。默认为 None
。
violation_error_message
¶
- BaseConstraint.violation_error_message¶
在 模型验证期间引发 ValidationError
时使用的错误消息。默认为 "Constraint “%(name)s” is violated."
。
validate()
¶
验证在 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")
自 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(fields=['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.DEFERRED
或 Deferrable.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¶
一个字段名称列表或元组,作为非键列包含在覆盖唯一索引中。这允许仅使用索引扫描来执行仅选择包含字段 (include
) 并仅按唯一字段 (fields
) 过滤的查询。
例如
UniqueConstraint(name="unique_booking", fields=["room", "date"], include=["full_name"])
允许根据 room
和 date
进行过滤,同时选择 full_name
,同时仅从索引中提取数据。
除了 PostgreSQL 之外的数据库忽略具有非键列的唯一约束。
非键列与 Index.include
具有相同的数据库限制。
opclasses
¶
- UniqueConstraint.opclasses¶
要为此唯一索引使用的 PostgreSQL 运算符类 的名称。如果您需要自定义运算符类,则必须为索引中的每个字段提供一个。
例如
UniqueConstraint(
name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
)
在 username
上创建一个使用 varchar_pattern_ops
的唯一索引。
除了 PostgreSQL 之外的数据库忽略 opclasses
。
nulls_distinct
¶
- UniqueConstraint.nulls_distinct¶
是否应将唯一约束覆盖的包含 NULL
值的行视为彼此不同。默认值为 None
,它使用数据库默认值,在大多数后端上为 True
。
例如
UniqueConstraint(name="ordering", fields=["ordering"], nulls_distinct=False)
创建一个唯一约束,只允许一行在 ordering
列中存储 NULL
值。
除了 PostgreSQL 15+ 之外的数据库忽略具有 nulls_distinct
的唯一约束。
violation_error_code
¶
- UniqueConstraint.violation_error_code¶
在 模型验证期间引发 ValidationError
时使用的错误代码。默认为 None
。
此代码不用于具有 UniqueConstraint
的 fields
并且没有 condition
的 UniqueConstraint
。此类 UniqueConstraint
与使用 Field.unique
或在 Meta.unique_together
中定义的约束具有相同的错误代码。
violation_error_message
¶
- UniqueConstraint.violation_error_message¶
在 模型验证期间引发 ValidationError
时使用的错误消息。默认为 BaseConstraint.violation_error_message
。
此消息不用于具有 UniqueConstraint
的 fields
并且没有 condition
的 UniqueConstraint
。此类 UniqueConstraint
显示与使用 Field.unique
或在 Meta.unique_together
中定义的约束相同的消息。