约束参考
本模块中定义的类可以创建数据库约束。它们被添加到模型中 Meta.constraints
选项中。
引用内置约束
约束是在 django.db.models.constraint
中定义的,但为了方便,它们被导入到 django.db.models 中。标准的惯例是使用 from django.db import models
作为 models.<Foo>Constraint
。
抽象基类中的约束
You must always specify a unique name for the constraint. As such, you cannot normally specify a constraint on an abstract base class, since the Meta.constraints option is inherited by subclasses, with exactly the same values for the attributes (including name
) each time. To work around name collisions, part of the name may contain '%(app_label)s'
and '%(class)s'
, which are replaced, respectively, by the lowercased app label and class name of the concrete model. For example 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)[源代码]
所有约束的基类。子类必须实现 constraint_sql()
, create_sql()
, remove_sql()
和 validate()
方法。
5.0 版后已移除: 不再支持传递位置参数。
所有约束都有以下共同的参数:
name
BaseConstraint.name
约束的名称。你必须始终为约束指定一个唯一的名称。
violation_error_code
New in Django 5.0.
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)[源代码]
验证在 model
上定义的约束是否在 instance
上被遵守。这将在数据库上执行一个查询,以确保该约束被遵守。如果需要使用 exclude
列表中的字段来验证约束,则会忽略该约束。
如果违反了约束,则引发 ValidationError
。
这个方法必须由子类来实现。
CheckConstraint
class CheckConstraint
(*, condition, name, violation_error_code=None, violation_error_message=None)[源代码]
在数据库中创建一个检查约束
condition
CheckConstraint.condition
A Q object or boolean Expression that specifies the conditional check you want the constraint to enforce.
For example, CheckConstraint(condition=Q(age__gte=18), name='age_gte_18')
ensures the age field is never less than 18.
表达式顺序
Q
参数的顺序未必会被保留,但 Q
表达式本身的顺序会被保留。这对于一些为了性能原因而保留检查约束表达式顺序的数据库可能很重要。例如,如果顺序很重要,请使用以下格式:
CheckConstraint(
condition=Q(age__gte=18) & Q(expensive_check=condition),
name="age_gte_18_and_others",
)
Oracle < 23c
Checks with nullable fields on Oracle < 23c must include a condition allowing for NULL
values in order for validate() to behave the same as check constraints validation. For example, if age
is a nullable field:
CheckConstraint(condition=Q(age__gte=18) | Q(age__isnull=True), name="age_gte_18")
5.1 版后已移除: The check
attribute is deprecated in favor of 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)[源代码]
在数据库中创建一个唯一约束。
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
,同时只从索引中获取数据。
非主键列的唯一约束在除了 PostgreSQL 之外的数据库中被忽略。
非关键列具有与 Index.include 相同的数据库限制。
opclasses
UniqueConstraint.opclasses
用于此唯一索引的 PostgreSQL 操作符类别 的名称。如果需要自定义操作符类别,必须为索引中的每个字段提供一个。
例子:
UniqueConstraint(
name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
)
使用 varchar_pattern_ops
在 username
上创建了一个唯一索引。
opclasses
对于 PostgreSQL 以外的数据库来说是被忽略的。
nulls_distinct
New in Django 5.0.
UniqueConstraint.nulls_distinct
是否应该将包含 NULL
值的行视为彼此不同,而不是唯一约束覆盖它们。默认值是 None
,它使用数据库默认值,在大多数后端上为 True
。
例子:
UniqueConstraint(name="ordering", fields=["ordering"], nulls_distinct=False)
创建一个唯一约束,只允许一行在 ordering
列中存储一个 NULL
值。
非主键列的唯一约束在除了 PostgreSQL 15+ 之外的数据库中被忽略。
violation_error_code
New in Django 5.0.
UniqueConstraint.violation_error_code
在 模型验证 过程中引发 ValidationError
时使用的错误代码。默认值为 None
。
对于没有 condition 且具有 fields 的 UniqueConstraint,此代码 不会被使用。这样的 UniqueConstraint 具有与通过 Field.unique 定义的或者在 Meta.unique_together 中定义的约束相同的错误代码。
violation_error_message
UniqueConstraint.violation_error_message
在 模型验证 期间引发 ValidationError
时使用的错误消息。默认为 BaseConstraint.violation_error_message。
这个消息 不会 用于没有 condition 且带有 fields 的 UniqueConstraint。这样的 UniqueConstraint 显示与使用 Field.unique 或 Meta.unique_together 定义的约束相同的消息。