Справочник по ограничениям
Классы, определённые в этом модуле, создают ограничения базы данных. Они добавляются в параметр модели 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(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().
У всех ограничений есть следующие общие параметры:
name
-
BaseConstraint.name
Имя ограничения. Вы всегда должны указать уникальное имя для ограничения.
violation_error_message
-
BaseConstraint.violation_error_message
Сообщение об ошибке, используемое при возникновении ValidationError во время проверки модели. По умолчанию "Constraint “%(name)s” is violated.".
validate()
-
BaseConstraint.validate(model, instance, exclude=None, using=DEFAULT_DB_ALIAS)
Проверяет, соблюдается ли ограничение, определённое на model, для instance. Это выполнит запрос к базе данных для проверки соблюдения ограничения. Если для проверки ограничения необходимы поля из списка exclude, ограничение игнорируется.
Вызвать ValidationError в случае нарушения ограничения.
Этот метод должен быть реализован подклассом.
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
Проверки с полями null в Oracle должны включать условие, допускающее NULL значения, чтобы validate() вело себя так же, как и проверка ограничений. Например, если age — это поле с возможностью null:
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(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, извлекая данные только из индекса.
include поддерживается только в PostgreSQL.
Столбцы, не являющиеся ключевыми, имеют те же ограничения базы данных, что и Index.include.
opclasses
-
UniqueConstraint.opclasses
Имена операторов классов PostgreSQL для использования в этом уникальном индексе. Если вам нужен пользовательский класс оператора, вы должны предоставить его для каждого поля в индексе.
Например:
UniqueConstraint(
name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
)
создаёт уникальный индекс на username, используя varchar_pattern_ops.
opclasses игнорируются для баз данных, кроме PostgreSQL.
violation_error_message
-
UniqueConstraint.violation_error_message
Сообщение об ошибке, используемое при поднятии ValidationError во время валидации модели. По умолчанию равно BaseConstraint.violation_error_message.
Это сообщение не используется для UniqueConstraint с fields и без condition. Такие UniqueConstraint отображают то же сообщение, что и ограничения, определенные с помощью Field.unique или в Meta.unique_together.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.2/ref/models/constraints/