# Django 5.2.8 documentation

# PostgreSQL-specifika databasbegränsningar

PostgreSQL stöder ytterligare dataintegritetsbegränsningar tillgängliga från modulen `django.contrib.postgres.constraints`. De läggs till i modellen `Meta.constraints` alternativ.

## `Uteslutningsbegränsning`

class ExclusionConstraint(*, name, expressions, index_type=None, condition=None, deferrable=None, include=None, violation_error_code=None, violation_error_message=None)

  Skapar en uteslutningsbegränsning i databasen. Internt implementerar PostgreSQL uteslutningsbegränsningar med hjälp av index. Standardindextypen är GiST. För att använda dem måste du aktivera btree_gist-tillägget på PostgreSQL. Du kan installera den med hjälp av `BtreeGistExtension` migreringsoperation.

  Om du försöker infoga en ny rad som står i konflikt med en befintlig rad, uppstår ett `IntegrityError`. På samma sätt när en uppdatering står i konflikt med en befintlig rad.

  Begränsningar för uteslutning kontrolleras under modellvalidering.

### `namn`

ExclusionConstraint.name

Se `BaseConstraint.name`.

### `uttryck`

ExclusionConstraint.expressions

En iterabel med 2-tuples. Det första elementet är ett uttryck eller en sträng. Det andra elementet är en SQL-operator som representeras som en sträng. För att undvika skrivfel kan du använda `RangeOperators` som mappar operatörerna med strängar. Till exempel:

    expressions = [
        ("timespan", RangeOperators.ADJACENT_TO),
        (F("room"), RangeOperators.EQUAL),
    ]

Begränsningar för operatörer.

Endast kommutativa operatorer kan användas i uteslutningsbegränsningar.

Uttrycket `OpClass()` kan användas för att ange en anpassad operatorklass för begränsningsuttrycken. Till exempel:

    expressions = [
        (OpClass("circle", name="circle_ops"), RangeOperators.OVERLAPS),
    ]

skapar en uteslutningsbegränsning på `circle` med hjälp av `circle_ops`.

### `index_typ`

ExclusionConstraint.index_type

Indextypen för begränsningen. Accepterade värden är `GIST` eller `SPGIST`. Matchningen är okänslig för skiftlägesskillnader. Om det inte anges är standardindextypen `GIST`.

### `villkor`

ExclusionConstraint.condition

Ett `Q`-objekt som anger villkoret för att begränsa en begränsning till en delmängd av rader. Till exempel:, `condition=Q(cancelled=False)`.

Dessa villkor har samma databasrestriktioner som `django.db.models.Index.condition`.

### `deferrable`

ExclusionConstraint.deferrable

Ange denna parameter för att skapa en uppskjutbar uteslutningsbegränsning. Accepterade värden är `Deferrable.DEFERRED` eller `Deferrable.IMMEDIATE`. Till exempel:

    from django.contrib.postgres.constraints import ExclusionConstraint
    from django.contrib.postgres.fields import RangeOperators
    from django.db.models import Deferrable

    ExclusionConstraint(
        name="exclude_overlapping_deferred",
        expressions=[
            ("timespan", RangeOperators.OVERLAPS),
        ],
        deferrable=Deferrable.DEFERRED,
    )

Som standard är begränsningar inte uppskjutna. En uppskjuten begränsning kommer inte att verkställas förrän i slutet av transaktionen. En omedelbar begränsning kommer att verkställas omedelbart efter varje kommando.

Varning

Uppskjutna uteslutningsbegränsningar kan leda till en ”prestandaförlust” <https://www.postgresql.org/docs/current/sql-createtable.html#id-1.9.3.85.9.4>`_.

### `inkludera`

ExclusionConstraint.include

En lista eller tupel med namnen på de fält som ska ingå i det täckande uteslutningsvillkoret som icke-nyckelkolumner. Detta gör det möjligt att använda skanningar med enbart index för frågor som endast väljer inkluderade fält (`include`) och endast filtrerar efter indexerade fält (`expressions`).

`include` stöds för GiST-index. PostgreSQL 14+ stöder också `include` för SP-GiST-index.

### `Felkod för överträdelse`

ExclusionConstraint.violation_error_code

Den felkod som används när `ValidationError` uppstår under modellvalidering. Standardvärdet är `None`.

### `avvikelse_felmeddelande`

Det felmeddelande som används när `ValidationError` uppstår under modellvalidering. Standardvärdet är `BaseConstraint.violation_error_message`.

### Exempel

Följande exempel begränsar överlappande bokningar i samma rum, utan att ta hänsyn till avbokade bokningar:

    from django.contrib.postgres.constraints import ExclusionConstraint
    from django.contrib.postgres.fields import DateTimeRangeField, RangeOperators
    from django.db import models
    from django.db.models import Q

    class Room(models.Model):
        number = models.IntegerField()

    class Reservation(models.Model):
        room = models.ForeignKey("Room", on_delete=models.CASCADE)
        timespan = DateTimeRangeField()
        cancelled = models.BooleanField(default=False)

        class Meta:
            constraints = [
                ExclusionConstraint(
                    name="exclude_overlapping_reservations",
                    expressions=[
                        ("timespan", RangeOperators.OVERLAPS),
                        ("room", RangeOperators.EQUAL),
                    ],
                    condition=Q(cancelled=False),
                ),
            ]

Om din modell definierar ett intervall med två fält, istället för de ursprungliga PostgreSQL-intervalltyperna, bör du skriva ett uttryck som använder motsvarande funktion (t.ex. `` TsTzRange() `) och använda avgränsarna för fältet. Oftast kommer avgränsarna att vara ``'[)'`, vilket innebär att den nedre gränsen är inkluderande och den övre gränsen är exkluderande. Du kan använda `RangeBoundary` som tillhandahåller en uttrycksmappning för intervallgränserna. Till exempel:

    from django.contrib.postgres.constraints import ExclusionConstraint
    from django.contrib.postgres.fields import (
        DateTimeRangeField,
        RangeBoundary,
        RangeOperators,
    )
    from django.db import models
    from django.db.models import Func, Q

    class TsTzRange(Func):
        function = "TSTZRANGE"
        output_field = DateTimeRangeField()

    class Reservation(models.Model):
        room = models.ForeignKey("Room", on_delete=models.CASCADE)
        start = models.DateTimeField()
        end = models.DateTimeField()
        cancelled = models.BooleanField(default=False)

        class Meta:
            constraints = [
                ExclusionConstraint(
                    name="exclude_overlapping_reservations",
                    expressions=[
                        (
                            TsTzRange("start", "end", RangeBoundary()),
                            RangeOperators.OVERLAPS,
                        ),
                        ("room", RangeOperators.EQUAL),
                    ],
                    condition=Q(cancelled=False),
                ),
            ]