约束参考¶
本模块中定义的类可以创建数据库约束。它们被添加到模型中 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')
。
约束的验证
约束在 模型验证 过程中进行检查。
对于 JSONField
的约束验证
包含 JSONField
的约束可能不会引发验证错误,因为键、索引和路径转换具有许多与数据库相关的注意事项。这个问题 可能在以后被完全支持。
您应该始终检查是否有来自 django.db.models
记录器的日志消息,例如 "在...上调用 check() 时出现了数据库错误",以确认它已正确验证。
在旧版本中,约束在模型验证期间不会被检查。
BaseConstraint
¶
-
class
BaseConstraint
(name, violation_error_message=None)¶ 所有约束的基类。子类必须实现
constraint_sql()
,create_sql()
,remove_sql()
和validate()
方法。
所有约束都有以下共同的参数:
CheckConstraint
¶
-
class
CheckConstraint
(*, check, name, violation_error_message=None)¶ 在数据库中创建一个检查约束
check
¶
-
CheckConstraint.
check
¶
一个 Q
对象或布尔值 Expression
,它指定了你要强制约束的检查。
例如,CheckConstraint(check=Q(age__gte=18), name='age_gte_18')
确保年龄字段永远不小于 18。
Oracle
在 Oracle 上对可空字段进行检查时,必须包含一个允许 NULL
值的条件,以使 validate()
的行为与检查约束验证相同。例如,如果 age
是可空字段:
CheckConstraint(check=Q(age__gte=18) | Q(age__isnull=True), name="age_gte_18")
添加了``violation_error_message`` 参数。
UniqueConstraint
¶
-
class
UniqueConstraint
(*expressions, fields=(), name=None, condition=None, deferrable=None, include=None, opclasses=(), violation_error_message=None)¶ 在数据库中创建一个唯一约束。
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.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
,同时只从索引中获取数据。
include
只在 PostgreSQL 上支持。
非关键列具有与 Index.include
相同的数据库限制。
opclasses
¶
-
UniqueConstraint.
opclasses
¶
用于此唯一索引的 PostgreSQL 操作符类别 的名称。如果需要自定义操作符类别,必须为索引中的每个字段提供一个。
例子:
UniqueConstraint(
name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
)
使用 varchar_pattern_ops
在 username
上创建了一个唯一索引。
opclasses
对于 PostgreSQL 以外的数据库来说是被忽略的。
violation_error_message
¶
-
UniqueConstraint.
violation_error_message
¶
在 模型验证 期间引发 ValidationError
时使用的错误消息。默认为 BaseConstraint.violation_error_message
。
这个消息 不会 用于没有 condition
且带有 fields
的 UniqueConstraint
。这样的 UniqueConstraint
显示与使用 Field.unique
或 Meta.unique_together
定义的约束相同的消息。