约束参考

本模块中定义的类可以创建数据库约束。它们被添加到模型中 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 表达式本身的顺序会被保留。这对于一些为了性能原因而保留检查约束表达式顺序的数据库可能很重要。例如,如果顺序很重要,请使用以下格式:

  1. CheckConstraint(
  2. condition=Q(age__gte=18) & Q(expensive_check=condition),
  3. name="age_gte_18_and_others",
  4. )

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:

  1. 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 允许在表达式和数据库函数上创建功能性唯一约束。

例子:

  1. 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 对象,用于指定你想要强制执行的约束条件。

例子:

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

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

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

deferrable

UniqueConstraint.deferrable

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

  1. from django.db.models import Deferrable, UniqueConstraint
  2. UniqueConstraint(
  3. name="unique_order",
  4. fields=["order"],
  5. deferrable=Deferrable.DEFERRED,
  6. )

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

MySQL,MariaDB 和 SQLite。

在 MySQL、MariaDB 和 SQLite 上,可推迟的唯一约束被忽略,因为它们都不支持。

警告

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

include

UniqueConstraint.include

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

例子:

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

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

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

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

opclasses

UniqueConstraint.opclasses

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

例子:

  1. UniqueConstraint(
  2. name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
  3. )

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

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

nulls_distinct

New in Django 5.0.

UniqueConstraint.nulls_distinct

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

例子:

  1. 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 且具有 fieldsUniqueConstraint,此代码 不会被使用。这样的 UniqueConstraint 具有与通过 Field.unique 定义的或者在 Meta.unique_together 中定义的约束相同的错误代码。

violation_error_message

UniqueConstraint.violation_error_message

模型验证 期间引发 ValidationError 时使用的错误消息。默认为 BaseConstraint.violation_error_message

这个消息 不会 用于没有 condition 且带有 fieldsUniqueConstraint。这样的 UniqueConstraint 显示与使用 Field.uniqueMeta.unique_together 定义的约束相同的消息。