# Django 5.2.8 documentation

# 约束参考

本模块中定义的类可以创建数据库约束。它们被添加到模型中 `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()` 方法。

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

### `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)

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

如果违反了约束，则引发 `ValidationError`。

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

## `CheckConstraint`

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

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

### `condition`

CheckConstraint.condition

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

例子：

    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

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

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

## `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(fields=["room", "date"], name="unique_booking")

ensures each room can only be booked once for each date.

### `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。

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"])

将允许对 `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`

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`.