summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorHannes Ljungberg <hannes.ljungberg@gmail.com>2021-02-06 20:45:54 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-02-23 20:19:53 +0100
commit3aa545281e0c0f9fac93753e3769df9e0334dbaa (patch)
tree454bec922a78df9ecfe6eab197e7750e8a5bafac /docs
parent19ce1d493ae7cbc1e704d338077b1f5f5e5769c9 (diff)
Fixed #30916 -- Added support for functional unique constraints.
Thanks Ian Foote and Mariusz Felisiak for reviews.
Diffstat (limited to 'docs')
-rw-r--r--docs/ref/checks.txt2
-rw-r--r--docs/ref/contrib/postgres/indexes.txt22
-rw-r--r--docs/ref/models/constraints.txt22
-rw-r--r--docs/releases/4.0.txt30
4 files changed, 71 insertions, 5 deletions
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index 7761a2a323..dbba801e39 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -391,6 +391,8 @@ Models
* **models.W042**: Auto-created primary key used when not defining a primary
key type, by default ``django.db.models.AutoField``.
* **models.W043**: ``<database>`` does not support indexes on expressions.
+* **models.W044**: ``<database>`` does not support unique constraints on
+ expressions.
Security
--------
diff --git a/docs/ref/contrib/postgres/indexes.txt b/docs/ref/contrib/postgres/indexes.txt
index b6a4aba808..9a9b7fc73b 100644
--- a/docs/ref/contrib/postgres/indexes.txt
+++ b/docs/ref/contrib/postgres/indexes.txt
@@ -183,10 +183,10 @@ available from the ``django.contrib.postgres.indexes`` module.
.. class:: OpClass(expression, name)
An ``OpClass()`` expression represents the ``expression`` with a custom
- `operator class`_ that can be used to define functional indexes. To use it,
- you need to add ``'django.contrib.postgres'`` in your
- :setting:`INSTALLED_APPS`. Set the ``name`` parameter to the name of the
- `operator class`_.
+ `operator class`_ that can be used to define functional indexes or unique
+ constraints. To use it, you need to add ``'django.contrib.postgres'`` in
+ your :setting:`INSTALLED_APPS`. Set the ``name`` parameter to the name of
+ the `operator class`_.
For example::
@@ -197,4 +197,18 @@ available from the ``django.contrib.postgres.indexes`` module.
creates an index on ``Lower('username')`` using ``varchar_pattern_ops``.
+ Another example::
+
+ UniqueConstraint(
+ OpClass(Upper('description'), name='text_pattern_ops'),
+ name='upper_description_unique',
+ )
+
+ creates a unique constraint on ``Upper('description')`` using
+ ``text_pattern_ops``.
+
+ .. versionchanged:: 4.0
+
+ Support for functional unique constraints was added.
+
.. _operator class: https://www.postgresql.org/docs/current/indexes-opclass.html
diff --git a/docs/ref/models/constraints.txt b/docs/ref/models/constraints.txt
index e3b682d1c5..c675903db6 100644
--- a/docs/ref/models/constraints.txt
+++ b/docs/ref/models/constraints.txt
@@ -69,10 +69,30 @@ constraint.
``UniqueConstraint``
====================
-.. class:: UniqueConstraint(*, fields, name, condition=None, deferrable=None, include=None, opclasses=())
+.. class:: UniqueConstraint(*expressions, fields=(), name=None, condition=None, deferrable=None, include=None, opclasses=())
Creates a unique constraint in the database.
+``expressions``
+---------------
+
+.. attribute:: UniqueConstraint.expressions
+
+.. versionadded:: 4.0
+
+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``
----------
diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt
index f1a25d0d92..502aabd4d1 100644
--- a/docs/releases/4.0.txt
+++ b/docs/releases/4.0.txt
@@ -28,6 +28,36 @@ The Django 3.2.x series is the last to support Python 3.6 and 3.7.
What's new in Django 4.0
========================
+Functional unique constraints
+-----------------------------
+
+The new :attr:`*expressions <django.db.models.UniqueConstraint.expressions>`
+positional argument of
+:class:`UniqueConstraint() <django.db.models.UniqueConstraint>` enables
+creating functional unique constraints on expressions and database functions.
+For example::
+
+ from django.db import models
+ from django.db.models import UniqueConstraint
+ from django.db.models.functions import Lower
+
+
+ class MyModel(models.Model):
+ first_name = models.CharField(max_length=255)
+ last_name = models.CharField(max_length=255)
+
+ class Meta:
+ indexes = [
+ UniqueConstraint(
+ Lower('first_name'),
+ Lower('last_name').desc(),
+ name='first_last_name_unique',
+ ),
+ ]
+
+Functional unique constraints are added to models using the
+:attr:`Meta.constraints <django.db.models.Options.constraints>` option.
+
Minor features
--------------