mirror of
https://github.com/django/django.git
synced 2024-11-28 10:48:32 +01:00
004f985b91
Thanks Dan LaManna for the report.
270 lines
8.4 KiB
Plaintext
270 lines
8.4 KiB
Plaintext
=====================
|
|
Constraints reference
|
|
=====================
|
|
|
|
.. module:: django.db.models.constraints
|
|
|
|
.. currentmodule:: django.db.models
|
|
|
|
The classes defined in this module create database constraints. They are added
|
|
in the model :attr:`Meta.constraints <django.db.models.Options.constraints>`
|
|
option.
|
|
|
|
.. admonition:: Referencing built-in constraints
|
|
|
|
Constraints are defined in ``django.db.models.constraints``, but for
|
|
convenience they're imported into :mod:`django.db.models`. The standard
|
|
convention is to use ``from django.db import models`` and refer to the
|
|
constraints as ``models.<Foo>Constraint``.
|
|
|
|
.. admonition:: Constraints in abstract base classes
|
|
|
|
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
|
|
:attr:`Meta.constraints <django.db.models.Options.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(check=Q(age__gte=18),
|
|
name='%(app_label)s_%(class)s_is_adult')``.
|
|
|
|
.. admonition:: Validation of Constraints
|
|
|
|
Constraints are checked during the :ref:`model validation
|
|
<validating-objects>`.
|
|
|
|
.. admonition:: Validation of Constraints with ``JSONField``
|
|
|
|
Constraints containing :class:`~django.db.models.JSONField` may not raise
|
|
validation errors as key, index, and path transforms have many
|
|
database-specific caveats. This :ticket:`may be fully supported later
|
|
<34059>`.
|
|
|
|
You should always check that there are no log messages, in the
|
|
``django.db.models`` logger, like *"Got a database error calling check() on
|
|
…"* to confirm it's validated properly.
|
|
|
|
.. versionchanged:: 4.1
|
|
|
|
In older versions, constraints were not checked during model validation.
|
|
|
|
``BaseConstraint``
|
|
==================
|
|
|
|
.. class:: BaseConstraint(name, violation_error_message=None)
|
|
|
|
Base class for all constraints. Subclasses must implement
|
|
``constraint_sql()``, ``create_sql()``, ``remove_sql()`` and
|
|
``validate()`` methods.
|
|
|
|
All constraints have the following parameters in common:
|
|
|
|
``name``
|
|
--------
|
|
|
|
.. attribute:: BaseConstraint.name
|
|
|
|
The name of the constraint. You must always specify a unique name for the
|
|
constraint.
|
|
|
|
``violation_error_message``
|
|
---------------------------
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
.. attribute:: BaseConstraint.violation_error_message
|
|
|
|
The error message used when ``ValidationError`` is raised during
|
|
:ref:`model validation <validating-objects>`. Defaults to
|
|
``"Constraint “%(name)s” is violated."``.
|
|
|
|
``validate()``
|
|
--------------
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
.. method:: BaseConstraint.validate(model, instance, exclude=None, using=DEFAULT_DB_ALIAS)
|
|
|
|
Validates that the constraint, defined on ``model``, is respected on the
|
|
``instance``. This will do a query on the database to ensure that the
|
|
constraint is respected. If fields in the ``exclude`` list are needed to
|
|
validate the constraint, the constraint is ignored.
|
|
|
|
Raise a ``ValidationError`` if the constraint is violated.
|
|
|
|
This method must be implemented by a subclass.
|
|
|
|
``CheckConstraint``
|
|
===================
|
|
|
|
.. class:: CheckConstraint(*, check, name, violation_error_message=None)
|
|
|
|
Creates a check constraint in the database.
|
|
|
|
``check``
|
|
---------
|
|
|
|
.. attribute:: CheckConstraint.check
|
|
|
|
A :class:`Q` object or boolean :class:`~django.db.models.Expression` that
|
|
specifies the check you want the constraint to enforce.
|
|
|
|
For example, ``CheckConstraint(check=Q(age__gte=18), name='age_gte_18')``
|
|
ensures the age field is never less than 18.
|
|
|
|
.. admonition:: Oracle
|
|
|
|
Checks with nullable fields on Oracle must include a condition allowing for
|
|
``NULL`` values in order for :meth:`validate() <BaseConstraint.validate>`
|
|
to behave the same as check constraints validation. For example, if ``age``
|
|
is a nullable field::
|
|
|
|
CheckConstraint(check=Q(age__gte=18) | Q(age__isnull=True), name='age_gte_18')
|
|
|
|
.. versionchanged:: 4.1
|
|
|
|
The ``violation_error_message`` argument was added.
|
|
|
|
``UniqueConstraint``
|
|
====================
|
|
|
|
.. class:: UniqueConstraint(*expressions, fields=(), name=None, condition=None, deferrable=None, include=None, opclasses=(), violation_error_message=None)
|
|
|
|
Creates a unique constraint in the database.
|
|
|
|
``expressions``
|
|
---------------
|
|
|
|
.. attribute:: UniqueConstraint.expressions
|
|
|
|
Positional argument ``*expressions`` allows creating functional unique
|
|
constraints on expressions and database functions.
|
|
|
|
For example::
|
|
|
|
UniqueConstraint(Lower('name').desc(), 'category', name='unique_lower_name_category')
|
|
|
|
creates a unique constraint on the lowercased value of the ``name`` field in
|
|
descending order and the ``category`` field in the default ascending order.
|
|
|
|
Functional unique constraints have the same database restrictions as
|
|
:attr:`Index.expressions`.
|
|
|
|
``fields``
|
|
----------
|
|
|
|
.. attribute:: UniqueConstraint.fields
|
|
|
|
A list of field names that specifies the unique set of columns you want the
|
|
constraint to enforce.
|
|
|
|
For example, ``UniqueConstraint(fields=['room', 'date'],
|
|
name='unique_booking')`` ensures each room can only be booked once for each
|
|
date.
|
|
|
|
``condition``
|
|
-------------
|
|
|
|
.. attribute:: UniqueConstraint.condition
|
|
|
|
A :class:`Q` object that specifies the condition you want the constraint to
|
|
enforce.
|
|
|
|
For example::
|
|
|
|
UniqueConstraint(fields=['user'], condition=Q(status='DRAFT'), name='unique_draft_user')
|
|
|
|
ensures that each user only has one draft.
|
|
|
|
These conditions have the same database restrictions as
|
|
:attr:`Index.condition`.
|
|
|
|
``deferrable``
|
|
--------------
|
|
|
|
.. attribute:: UniqueConstraint.deferrable
|
|
|
|
Set this parameter to create a deferrable unique constraint. Accepted values
|
|
are ``Deferrable.DEFERRED`` or ``Deferrable.IMMEDIATE``. For example::
|
|
|
|
from django.db.models import Deferrable, UniqueConstraint
|
|
|
|
UniqueConstraint(
|
|
name='unique_order',
|
|
fields=['order'],
|
|
deferrable=Deferrable.DEFERRED,
|
|
)
|
|
|
|
By default constraints are not deferred. A deferred constraint will not be
|
|
enforced until the end of the transaction. An immediate constraint will be
|
|
enforced immediately after every command.
|
|
|
|
.. admonition:: MySQL, MariaDB, and SQLite.
|
|
|
|
Deferrable unique constraints are ignored on MySQL, MariaDB, and SQLite as
|
|
neither supports them.
|
|
|
|
.. warning::
|
|
|
|
Deferred unique constraints may lead to a `performance penalty
|
|
<https://www.postgresql.org/docs/current/sql-createtable.html#id-1.9.3.85.9.4>`_.
|
|
|
|
``include``
|
|
-----------
|
|
|
|
.. attribute:: UniqueConstraint.include
|
|
|
|
A list or tuple of the names of the fields to be included in the covering
|
|
unique index as non-key columns. This allows index-only scans to be used for
|
|
queries that select only included fields (:attr:`~UniqueConstraint.include`)
|
|
and filter only by unique fields (:attr:`~UniqueConstraint.fields`).
|
|
|
|
For example::
|
|
|
|
UniqueConstraint(name='unique_booking', fields=['room', 'date'], include=['full_name'])
|
|
|
|
will allow filtering on ``room`` and ``date``, also selecting ``full_name``,
|
|
while fetching data only from the index.
|
|
|
|
``include`` is supported only on PostgreSQL.
|
|
|
|
Non-key columns have the same database restrictions as :attr:`Index.include`.
|
|
|
|
|
|
``opclasses``
|
|
-------------
|
|
|
|
.. attribute:: UniqueConstraint.opclasses
|
|
|
|
The names of the `PostgreSQL operator classes
|
|
<https://www.postgresql.org/docs/current/indexes-opclass.html>`_ to use for
|
|
this unique index. If you require a custom operator class, you must provide one
|
|
for each field in the index.
|
|
|
|
For example::
|
|
|
|
UniqueConstraint(name='unique_username', fields=['username'], opclasses=['varchar_pattern_ops'])
|
|
|
|
creates a unique index on ``username`` using ``varchar_pattern_ops``.
|
|
|
|
``opclasses`` are ignored for databases besides PostgreSQL.
|
|
|
|
``violation_error_message``
|
|
---------------------------
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
.. attribute:: UniqueConstraint.violation_error_message
|
|
|
|
The error message used when ``ValidationError`` is raised during
|
|
:ref:`model validation <validating-objects>`. Defaults to
|
|
:attr:`.BaseConstraint.violation_error_message`.
|
|
|
|
This message is *not used* for :class:`UniqueConstraint`\s with
|
|
:attr:`~UniqueConstraint.fields` and without a
|
|
:attr:`~UniqueConstraint.condition`. Such :class:`~UniqueConstraint`\s show the
|
|
same message as constraints defined with
|
|
:attr:`.Field.unique` or in
|
|
:attr:`Meta.unique_together <django.db.models.Options.constraints>`.
|