{"title":"Contraintes de bases de données spécifiques à PostgreSQL","version":"3.0","locale":"fr","docname":"ref/contrib/postgres/constraints","url":"/fr/3.0/ref/contrib/postgres/constraints/","canonical":"https://djangodocs.dev/fr/3.0/ref/contrib/postgres/constraints/","summary":"PostgreSQL offre des contraintes d’intégrité de données supplémentaires dans le module django.contrib.postgres.constraints.","html":"<span id=\"postgresql-specific-database-constraints\"></span><h1>Contraintes de bases de données spécifiques à PostgreSQL<a class=\"heading-anchor\" href=\"#module-django.contrib.postgres.constraints\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>PostgreSQL offre des contraintes d’intégrité de données supplémentaires dans le module <code class=\"docutils literal notranslate\">django.contrib.postgres.constraints</code>. Elles sont ajoutées dans l’option <a class=\"reference internal\" href=\"/fr/3.0/ref/models/options/#django.db.models.Options.constraints\" title=\"django.db.models.Options.constraints\"><code class=\"xref py py-attr docutils literal notranslate\">Meta.constraints</code></a> des modèles.</p>\n<section id=\"exclusionconstraint\">\n<h2><code class=\"docutils literal notranslate\">ExclusionConstraint</code><a class=\"heading-anchor\" href=\"#exclusionconstraint\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"version-note version-added\" data-version=\"3.0\" role=\"note\">\n<p class=\"version-note-title\">New in Django 3.0</p></aside>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.constraints.ExclusionConstraint\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">ExclusionConstraint</span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"keyword-only-separator o\"><abbr title=\"Keyword-only parameters separator (PEP 3102)\">*</abbr></span></em>, <em class=\"sig-param\">name</em>, <em class=\"sig-param\">expressions</em>, <em class=\"sig-param\">index_type<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">condition<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.constraints.ExclusionConstraint\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Crée une contrainte d’exclusion dans la base de données. En interne, PostgreSQL implémente les contraintes d’exclusion par des index. Le type d’index par défaut est <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/gist.html\">GiST</a>. Pour les utiliser, vous devez activer <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/btree-gist.html\">l’extension btree_gist</a> dans PostgreSQL. Vous pouvez installer l’extension par une opération de migration <a class=\"reference internal\" href=\"/fr/3.0/ref/contrib/postgres/operations/#django.contrib.postgres.operations.BtreeGistExtension\" title=\"django.contrib.postgres.operations.BtreeGistExtension\"><code class=\"xref py py-class docutils literal notranslate\">BtreeGistExtension</code></a>.</p>\n<p>Si vous essayez d’insérer une nouvelle ligne qui entre en conflit avec une ligne existante, une erreur <a class=\"reference internal\" href=\"/fr/3.0/ref/exceptions/#django.db.IntegrityError\" title=\"django.db.IntegrityError\"><code class=\"xref py py-exc docutils literal notranslate\">IntegrityError</code></a> se produit. De même lorsqu’un conflit survient lors d’une mise à jour.</p>\n</dd></dl>\n\n<section id=\"name\">\n<h3><code class=\"docutils literal notranslate\">name</code><a class=\"heading-anchor\" href=\"#name\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.constraints.ExclusionConstraint.name\">\n<span class=\"sig-prename descclassname\">ExclusionConstraint.</span><span class=\"sig-name descname\">name</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.constraints.ExclusionConstraint.name\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Le nom de la contrainte.</p>\n</section>\n<section id=\"expressions\">\n<h3><code class=\"docutils literal notranslate\">expressions</code><a class=\"heading-anchor\" href=\"#expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.constraints.ExclusionConstraint.expressions\">\n<span class=\"sig-prename descclassname\">ExclusionConstraint.</span><span class=\"sig-name descname\">expressions</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.constraints.ExclusionConstraint.expressions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un itérable de tuples binaires. Le premier élément est une expression ou une chaîne. Le second élément est un opérateur SQL sous forme de chaîne. Pour éviter les erreurs syntaxiques, vous pouvez utiliser <a class=\"reference internal\" href=\"/fr/3.0/ref/contrib/postgres/fields/#django.contrib.postgres.fields.RangeOperators\" title=\"django.contrib.postgres.fields.RangeOperators\"><code class=\"xref py py-class docutils literal notranslate\">RangeOperators</code></a> qui fait correspondre les opérateurs à des chaînes. Par exemple</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>expressions<span class=\"o\">=</span><span class=\"p\">[</span>\n    <span class=\"p\">(</span><span class=\"s1\">&#39;timespan&#39;</span><span class=\"p\">,</span> RangeOperators<span class=\"o\">.</span>ADJACENT_TO<span class=\"p\">),</span>\n    <span class=\"p\">(</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;room&#39;</span><span class=\"p\">),</span> RangeOperators<span class=\"o\">.</span>EQUAL<span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<aside class=\"admonition-restrictions-on-operators admonition\" role=\"note\">\n<p class=\"admonition-title\">Restrictions sur les opérateurs.</p>\n<p>Seuls des opérateurs commutatifs peuvent être utilisés dans des contraintes d’exclusion.</p>\n</aside>\n</section>\n<section id=\"index-type\">\n<h3><code class=\"docutils literal notranslate\">index_type</code><a class=\"heading-anchor\" href=\"#index-type\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.constraints.ExclusionConstraint.index_type\">\n<span class=\"sig-prename descclassname\">ExclusionConstraint.</span><span class=\"sig-name descname\">index_type</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.constraints.ExclusionConstraint.index_type\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Le type d’index de la contrainte. La valeurs admises sont <code class=\"docutils literal notranslate\">GIST</code> ou <code class=\"docutils literal notranslate\">SPGIST</code>. Les correspondances ne tiennent pas compte de la casse. En cas d’absence, le type d’index par défaut est <code class=\"docutils literal notranslate\">GIST</code>.</p>\n</section>\n<section id=\"condition\">\n<h3><code class=\"docutils literal notranslate\">condition</code><a class=\"heading-anchor\" href=\"#condition\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.constraints.ExclusionConstraint.condition\">\n<span class=\"sig-prename descclassname\">ExclusionConstraint.</span><span class=\"sig-name descname\">condition</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.constraints.ExclusionConstraint.condition\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un objet <a class=\"reference internal\" href=\"/fr/3.0/ref/models/querysets/#django.db.models.Q\" title=\"django.db.models.Q\"><code class=\"xref py py-class docutils literal notranslate\">Q</code></a> qui indique la condition de restriction d’une contrainte à un sous-ensemble de lignes. Par exemple, <code class=\"docutils literal notranslate\">condition=Q(annule=False)</code>.</p>\n<p>Ces conditions sont soumises aux mêmes restrictions de base de données que <a class=\"reference internal\" href=\"/fr/3.0/ref/models/indexes/#django.db.models.Index.condition\" title=\"django.db.models.Index.condition\"><code class=\"xref py py-attr docutils literal notranslate\">django.db.models.Index.condition</code></a>.</p>\n</section>\n<section id=\"examples\">\n<h3>Exemples<a class=\"heading-anchor\" href=\"#examples\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’exemple suivant évite les chevauchements de réservations d’une même salle, sans tenir compte des réservations annulées</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.postgres.constraints</span> <span class=\"kn\">import</span> ExclusionConstraint\n<span class=\"kn\">from</span> <span class=\"nn\">django.contrib.postgres.fields</span> <span class=\"kn\">import</span> DateTimeRangeField<span class=\"p\">,</span> RangeOperators\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Q\n\n<span class=\"k\">class</span> <span class=\"nc\">Room</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    number <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Reservation</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    room <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span><span class=\"s1\">&#39;Room&#39;</span><span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    timespan <span class=\"o\">=</span> DateTimeRangeField<span class=\"p\">()</span>\n    cancelled <span class=\"o\">=</span> models<span class=\"o\">.</span>BooleanField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        constraints <span class=\"o\">=</span> <span class=\"p\">[</span>\n            ExclusionConstraint<span class=\"p\">(</span>\n                name<span class=\"o\">=</span><span class=\"s1\">&#39;exclude_overlapping_reservations&#39;</span><span class=\"p\">,</span>\n                expressions<span class=\"o\">=</span><span class=\"p\">[</span>\n                    <span class=\"p\">(</span><span class=\"s1\">&#39;timespan&#39;</span><span class=\"p\">,</span> RangeOperators<span class=\"o\">.</span>OVERLAPS<span class=\"p\">),</span>\n                    <span class=\"p\">(</span><span class=\"s1\">&#39;room&#39;</span><span class=\"p\">,</span> RangeOperators<span class=\"o\">.</span>EQUAL<span class=\"p\">),</span>\n                <span class=\"p\">],</span>\n                condition<span class=\"o\">=</span>Q<span class=\"p\">(</span>cancelled<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">),</span>\n            <span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n</code></pre></div>\n<p>Dans le cas où un modèle définit un intervalle avec deux champs, au lieu des types d’intervalle natifs de PostgreSQL, vous devriez écrire une expression qui utilise la fonction équivalente (par ex.  <code class=\"docutils literal notranslate\">TsTzRange()</code>), et utiliser les délimiteurs du champ. La plupart du temps, les délimiteurs seront <code class=\"docutils literal notranslate\">'[)'</code>, ce qui signifie que la limite inférieure est inclusive et la limite supérieure exclusive. Vous pouvez utiliser <a class=\"reference internal\" href=\"/fr/3.0/ref/contrib/postgres/fields/#django.contrib.postgres.fields.RangeBoundary\" title=\"django.contrib.postgres.fields.RangeBoundary\"><code class=\"xref py py-class docutils literal notranslate\">RangeBoundary</code></a> qui fournit des correspondances d’expression pour les <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-INCLUSIVITY\">limites d’intervalle</a>. Par exemple</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.postgres.constraints</span> <span class=\"kn\">import</span> ExclusionConstraint\n<span class=\"kn\">from</span> <span class=\"nn\">django.contrib.postgres.fields</span> <span class=\"kn\">import</span> <span class=\"p\">(</span>\n    DateTimeRangeField<span class=\"p\">,</span>\n    RangeBoundary<span class=\"p\">,</span>\n    RangeOperators<span class=\"p\">,</span>\n<span class=\"p\">)</span>\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Func<span class=\"p\">,</span> Q\n\n\n<span class=\"k\">class</span> <span class=\"nc\">TsTzRange</span><span class=\"p\">(</span>Func<span class=\"p\">):</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;TSTZRANGE&#39;</span>\n    output_field <span class=\"o\">=</span> DateTimeRangeField<span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Reservation</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    room <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span><span class=\"s1\">&#39;Room&#39;</span><span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    start <span class=\"o\">=</span> models<span class=\"o\">.</span>DateTimeField<span class=\"p\">()</span>\n    end <span class=\"o\">=</span> models<span class=\"o\">.</span>DateTimeField<span class=\"p\">()</span>\n    cancelled <span class=\"o\">=</span> models<span class=\"o\">.</span>BooleanField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        constraints <span class=\"o\">=</span> <span class=\"p\">[</span>\n            ExclusionConstraint<span class=\"p\">(</span>\n                name<span class=\"o\">=</span><span class=\"s1\">&#39;exclude_overlapping_reservations&#39;</span><span class=\"p\">,</span>\n                expressions<span class=\"o\">=</span><span class=\"p\">(</span>\n                    <span class=\"p\">(</span>TsTzRange<span class=\"p\">(</span><span class=\"s1\">&#39;start&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;end&#39;</span><span class=\"p\">,</span> RangeBoundary<span class=\"p\">()),</span> RangeOperators<span class=\"o\">.</span>OVERLAPS<span class=\"p\">),</span>\n                    <span class=\"p\">(</span><span class=\"s1\">&#39;room&#39;</span><span class=\"p\">,</span> RangeOperators<span class=\"o\">.</span>EQUAL<span class=\"p\">),</span>\n                <span class=\"p\">),</span>\n                condition<span class=\"o\">=</span>Q<span class=\"p\">(</span>cancelled<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">),</span>\n            <span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n</code></pre></div>\n</section>\n</section>","rootId":"module-django.contrib.postgres.constraints","toc":[{"title":"ExclusionConstraint","anchor":"exclusionconstraint","children":[{"title":"name","anchor":"name","children":[]},{"title":"expressions","anchor":"expressions","children":[]},{"title":"index_type","anchor":"index-type","children":[]},{"title":"condition","anchor":"condition","children":[]},{"title":"Exemples","anchor":"examples","children":[]}]}],"breadcrumbs":[{"docname":"ref/index","title":"Référence de l’API","url":"/fr/3.0/ref/"},{"docname":"ref/contrib/index","title":"Paquets contrib","url":"/fr/3.0/ref/contrib/"},{"docname":"ref/contrib/postgres/index","title":"django.contrib.postgres","url":"/fr/3.0/ref/contrib/postgres/"}],"prev":{"docname":"ref/contrib/postgres/aggregates","title":"Fonctions d’agrégation spécifiques à PostgreSQL","url":"/fr/3.0/ref/contrib/postgres/aggregates/"},"next":{"docname":"ref/contrib/postgres/fields","title":"Champs de modèles spécifiques à PostgreSQL","url":"/fr/3.0/ref/contrib/postgres/fields/"},"formats":{"html":"/fr/3.0/ref/contrib/postgres/constraints/","markdown":"/fr/3.0/ref/contrib/postgres/constraints.md","json":"/fr/3.0/ref/contrib/postgres/constraints.json"},"source":"https://github.com/django/django/blob/stable/3.0.x/docs/ref/contrib/postgres/constraints.txt","official":"https://docs.djangoproject.com/fr/3.0/ref/contrib/postgres/constraints/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}