# Django 5.2.8 documentation

# Frågeuttryck

Frågeuttryck beskriver ett värde eller en beräkning som kan användas som en del av en uppdatering, ett skapande, ett filter, en ordning efter, en annotering eller ett aggregat. När ett uttryck ger ett booleskt värde kan det användas direkt i filter. Det finns ett antal inbyggda uttryck (dokumenteras nedan) som kan användas för att hjälpa dig att skriva frågor. Uttryck kan kombineras, eller i vissa fall nästlas, för att bilda mer komplexa beräkningar.

## Stöd för aritmetik

Django stöder negation, addition, subtraktion, multiplikation, division, modulo aritmetik och power-operatorn på frågeuttryck med hjälp av Python-konstanter, variabler och till och med andra uttryck.

## Utgångsfält

Många av de uttryck som dokumenteras i detta avsnitt stöder en valfri parameter `output_field`. Om den anges kommer Django att ladda värdet i det fältet efter att ha hämtat det från databasen.

`output_field` tar en modellfältsinstans, som `IntegerField()` eller `BooleanField()`. Vanligtvis behöver fältet inte några argument, som `max_length`, eftersom fältargument avser datavalidering som inte kommer att utföras på uttryckets utdatavärde.

`output_field` krävs endast när Django inte automatiskt kan bestämma resultatets fälttyp, till exempel komplexa uttryck som blandar fälttyper. Om du till exempel lägger till en `DecimalField()` och en `FloatField()` krävs ett utmatningsfält, som `output_field=FloatField()`.

`output_field` also allows using custom fields that perform type conversions outside a specific model field context. For example, if you frequently need to perform date arithmetic with `timedelta`, you can create a custom field that handles the conversion, ensuring consistent results across databases. See Så här skapar du anpassade modellfält.

## Några exempel

    >>> from django.db.models import Count, F, Value
    >>> from django.db.models.functions import Length, Upper
    >>> from django.db.models.lookups import GreaterThan

    # Find companies that have more employees than chairs.
    >>> Company.objects.filter(num_employees__gt=F("num_chairs"))

    # Find companies that have at least twice as many employees
    # as chairs. Both the querysets below are equivalent.
    >>> Company.objects.filter(num_employees__gt=F("num_chairs") * 2)
    >>> Company.objects.filter(num_employees__gt=F("num_chairs") + F("num_chairs"))

    # How many chairs are needed for each company to seat all employees?
    >>> company = (
    ...     Company.objects.filter(num_employees__gt=F("num_chairs"))
    ...     .annotate(chairs_needed=F("num_employees") - F("num_chairs"))
    ...     .first()
    ... )
    >>> company.num_employees
    120
    >>> company.num_chairs
    50
    >>> company.chairs_needed
    70

    # Create a new company using expressions.
    >>> company = Company.objects.create(name="Google", ticker=Upper(Value("goog")))
    >>> company.ticker
    'GOOG'

    # Annotate models with an aggregated value. Both forms
    # below are equivalent.
    >>> Company.objects.annotate(num_products=Count("products"))
    >>> Company.objects.annotate(num_products=Count(F("products")))

    # Aggregates can contain complex computations also
    >>> Company.objects.annotate(num_offerings=Count(F("products") + F("services")))

    # Expressions can also be used in order_by(), either directly
    >>> Company.objects.order_by(Length("name").asc())
    >>> Company.objects.order_by(Length("name").desc())
    # or using the double underscore lookup syntax.
    >>> from django.db.models import CharField
    >>> from django.db.models.functions import Length
    >>> CharField.register_lookup(Length)
    >>> Company.objects.order_by("name__length")

    # Boolean expression can be used directly in filters.
    >>> from django.db.models import Exists, OuterRef
    >>> Company.objects.filter(
    ...     Exists(Employee.objects.filter(company=OuterRef("pk"), salary__gt=10))
    ... )

    # Lookup expressions can also be used directly in filters
    >>> Company.objects.filter(GreaterThan(F("num_employees"), F("num_chairs")))
    # or annotations.
    >>> Company.objects.annotate(
    ...     need_chairs=GreaterThan(F("num_employees"), F("num_chairs")),
    ... )

## Inbyggda uttryck

Observera

Dessa uttryck definieras i `django.db.models.expressions` och `django.db.models.aggregates`, men för enkelhetens skull är de tillgängliga och importeras vanligtvis från `django.db.models`.

### `F()`-uttryck

class F

Ett `F()`-objekt representerar värdet av ett modellfält, transformerat värde av ett modellfält eller annoterad kolumn. Det gör det möjligt att referera till modellfältsvärden och utföra databasoperationer med hjälp av dem utan att faktiskt behöva dra ut dem från databasen till Python-minnet.

Istället använder Django objektet `F()` för att generera ett SQL-uttryck som beskriver den nödvändiga operationen på databasnivå.

Låt oss prova detta med ett exempel. Normalt kan man göra något liknande:

    # Tintin filed a news story!
    reporter = Reporters.objects.get(name="Tintin")
    reporter.stories_filed += 1
    reporter.save()

Här har vi hämtat värdet av `reporter.stories_filed` från databasen till minnet och manipulerat det med hjälp av välkända Python-operatorer, och sedan sparat objektet tillbaka till databasen. Men istället kunde vi också ha gjort:

    from django.db.models import F

    reporter = Reporters.objects.get(name="Tintin")
    reporter.stories_filed = F("stories_filed") + 1
    reporter.save()

Även om `reporter.stories_filed = F('stories_filed') + 1` ser ut som en normal Python-tilldelning av värde till ett instansattribut, är det i själva verket en SQL-konstruktion som beskriver en operation i databasen.

När Django stöter på en instans av `F()` åsidosätter den Pythons standardoperatorer för att skapa ett inkapslat SQL-uttryck; i det här fallet ett som instruerar databasen att öka databasfältet som representeras av `reporter.stories_filed`.

Oavsett vilket värde som finns eller fanns på `reporter.stories_filed` får Python aldrig veta något om det - det hanteras helt och hållet av databasen. Allt Python gör, genom Djangos `F()`-klass, är att skapa SQL-syntaxen för att hänvisa till fältet och beskriva operationen.

As well as being used in operations on single instances as above, `F()` can be used with `update()` to perform bulk updates on a `QuerySet`. This reduces the two queries we were using above - the `get()` and the `save()` - to just one:

    reporter = Reporters.objects.filter(name="Tintin")
    reporter.update(stories_filed=F("stories_filed") + 1)

We can also use `update()` to increment the field value on multiple objects - which could be very much faster than pulling them all into Python from the database, looping over them, incrementing the field value of each one, and saving each one back to the database:

    Reporter.objects.update(stories_filed=F("stories_filed") + 1)

`F()` kan därför erbjuda prestandafördelar genom:

- att få databasen, snarare än Python, att göra jobbet

- minska antalet förfrågningar som vissa operationer kräver

#### Skivning av `F()`-uttryck

För strängbaserade fält, textbaserade fält och `ArrayField` kan du använda Pythons syntax för array-slicing. Indexen är 0-baserade. Argumentet `step` till `slice` och negativ indexering stöds inte. Till exempel:

    >>> # Replacing a name with a substring of itself.
    >>> writer = Writers.objects.get(name="Priyansh")
    >>> writer.name = F("name")[1:5]
    >>> writer.save()
    >>> writer.name
    'riya'

#### Undvika tävlingsförhållanden med hjälp av `F()`

En annan fördel med `F()` är att om databasen - snarare än Python - uppdaterar ett fälts värde undviks ett race condition.

Om två Python-trådar kör koden i det första exemplet ovan kan den ena tråden hämta, öka och spara ett fälts värde efter att den andra har hämtat det från databasen. Det värde som den andra tråden sparar kommer att baseras på det ursprungliga värdet; den första trådens arbete kommer att gå förlorat.

If the database is responsible for updating the field, the process is more robust: it will only ever update the field based on the value of the field in the database when the `save()` or `update()` is executed, rather than based on its value when the instance was retrieved.

#### `F()` assignments are refreshed after `Model.save()`

`F()` objects assigned to model fields are refreshed from the database on `save()` on backends that support it without incurring a subsequent query (SQLite, PostgreSQL, and Oracle) and deferred otherwise (MySQL or MariaDB). For example:

    >>> reporter = Reporters.objects.get(name="Tintin")
    >>> reporter.stories_filed = F("stories_filed") + 1
    >>> reporter.save()
    >>> reporter.stories_filed  # This triggers a refresh query on MySQL/MariaDB.
    14  # Assuming the database value was 13 when the object was saved.

Changed in Django 6.0:

In previous versions of Django, `F()` objects were not refreshed from the database on `save()` which resulted in them being evaluated and persisted every time the instance was saved.

#### Använda `F()` i filter

`F()` är också mycket användbart i `QuerySet`-filter, där de gör det möjligt att filtrera en uppsättning objekt mot kriterier baserade på deras fältvärden, snarare än på Python-värden.

Detta finns dokumenterat i Använda F()-uttryck i frågor.

#### Använda `F()` med annotationer

`F()` kan användas för att skapa dynamiska fält i dina modeller genom att kombinera olika fält med aritmetik:

    company = Company.objects.annotate(chairs_needed=F("num_employees") - F("num_chairs"))

Om de fält som du kombinerar är av olika typer måste du tala om för Django vilken typ av fält som ska returneras. De flesta uttryck stöder output_field för detta fall, men eftersom `F()` inte gör det, måste du omsluta uttrycket med `ExpressionWrapper`:

    from django.db.models import DateTimeField, ExpressionWrapper, F

    Ticket.objects.annotate(
        expires=ExpressionWrapper(
            F("active_at") + F("duration"), output_field=DateTimeField()
        )
    )

Vid hänvisning till relationsfält som `ForeignKey` returnerar `F()` primärnyckelvärdet i stället för en modellinstans:

    >>> car = Company.objects.annotate(built_by=F("manufacturer"))[0]
    >>> car.manufacturer
    <Manufacturer: Toyota>
    >>> car.built_by
    3

#### Använda `F()` för att sortera nollvärden

Använd `F()` och nyckelordsargumentet `nulls_first` eller `nulls_last` till `Expression.asc()` eller `desc()` för att styra ordningsföljden för ett fälts null-värden. Som standard beror ordningsföljden på din databas.

Till exempel:, för att sortera företag som inte har kontaktats (`last_contacted` är null) efter företag som har kontaktats:

    from django.db.models import F

    Company.objects.order_by(F("last_contacted").desc(nulls_last=True))

#### Använda `F()` med logiska operationer

`F()`-uttryck som ger `BooleanField` kan logiskt negeras med inversionsoperatorn `~F()`. Till exempel:, för att byta aktiveringsstatus för företag:

    from django.db.models import F

    Company.objects.update(is_active=~F("is_active"))

### `Func()` uttryck

`Func()`-uttryck är bastypen för alla uttryck som involverar databasfunktioner som `COALESCE` och `LOWER`, eller aggregat som `SUM`. De kan användas direkt:

    from django.db.models import F, Func

    queryset.annotate(field_lower=Func(F("field"), function="LOWER"))

eller så kan de användas för att bygga upp ett bibliotek med databasfunktioner:

    class Lower(Func):
        function = "LOWER"

    queryset.annotate(field_lower=Lower("field"))

Men båda fallen kommer att resultera i en frågeuppsättning där varje modell är annoterad med ett extra attribut `field_lower` som produceras, ungefär, från följande SQL:

    SELECT
        ...
        LOWER("db_table"."field") as "field_lower"

See Databasfunktioner for a list of built-in database functions.

API:et `Func` är uppbyggt enligt följande:

class Func(*expressions, **extra)
  function

    Ett klassattribut som beskriver den funktion som ska genereras. Specifikt kommer `funktionen` att interpoleras som `funktion` platshållare inom `template`. Standardvärdet är `None`.

  template

    Ett klassattribut, i form av en formatsträng, som beskriver den SQL som genereras för denna funktion. Standardvärdet är `'%(function)s(%(expressions)s)'`.

    Om du konstruerar SQL som `strftime('%W', 'date')` och behöver ett bokstavligt `%`-tecken i frågan, fyrdubblar du det (`%%%%`) i attributet `template` eftersom strängen interpoleras två gånger: en gång under mallinterpolationen i `as_sql()` och en gång i SQL-interpolationen med frågeparametrarna i databasmarkören.

  arg_joiner

    Ett klassattribut som anger det tecken som används för att sammanfoga listan med `uttryck`. Standardvärden är `', '`.

  arity

    Ett klassattribut som anger antalet argument som funktionen accepterar. Om detta attribut är inställt och funktionen anropas med ett annat antal uttryck, kommer `TypeError` att uppstå. Standardvärde är `None`.

  as_sql(compiler, connection, function=None, template=None, arg_joiner=None, **extra_context)

    Genererar SQL-fragmentet för databasfunktionen. Returnerar en tupel `(sql, params)`, där `sql` är SQL-strängen och `params` är listan eller tupeln med frågeparametrar.

    Metoderna `as_vendor()` bör använda parametrarna `function`, `template`, `arg_joiner` och alla andra `**extra_context` för att anpassa SQL efter behov. Ett exempel:

    `django/db/modeller/functions.py`

        class ConcatPair(Func):
            ...
            function = "CONCAT"
            ...

            def as_mysql(self, compiler, connection, **extra_context):
                return super().as_sql(
                    compiler,
                    connection,
                    function="CONCAT_WS",
                    template="%(function)s('', %(expressions)s)",
                    **extra_context
                )

    För att undvika en SQL-injektionssårbarhet får `extra_context` inte innehålla otillförlitlig användarinmatning eftersom dessa värden interpoleras in i SQL-strängen i stället för att skickas som frågeparametrar, där databasdrivrutinen skulle undkomma dem.

Argumentet `*expressions` är en lista med positionella uttryck som funktionen ska tillämpas på. Uttrycken konverteras till strängar, sammanfogas med `arg_joiner` och interpoleras sedan in i `mallen` som platshållaren `expressions`.

Positionella argument kan vara uttryck eller Python-värden. Strängar antas vara kolumnreferenser och kommer att packas in i `F()` uttryck medan andra värden kommer att packas in i `Value()` uttryck.

De `**extra` kwargs är `key=value` par som kan interpoleras in i `template` attributet. För att undvika en SQL-injektionssårbarhet, `extra` får inte innehålla otillförlitlig användarinmatning eftersom dessa värden interpoleras in i SQL-strängen i stället för att skickas som frågeparametrar, där databasdrivrutinen skulle undkomma dem.

Nyckelorden `function`, `template` och `arg_joiner` kan användas för att ersätta attribut med samma namn utan att behöva definiera en egen klass. output_field kan användas för att definiera den förväntade returtypen.

### uttryck för `Aggregate()`

Ett aggregatuttryck är ett specialfall av ett Func()-uttryck som informerar frågan om att en `GROUP BY`-klausul krävs. Alla aggregate-funktioner, som `Sum()` och `Count()`, ärver från `Aggregate()`.

Eftersom `Aggregate` är uttryck och omslagsuttryck kan du representera vissa komplexa beräkningar:

    from django.db.models import Count

    Company.objects.annotate(
        managers_required=(Count("num_employees") / 4) + Count("num_managers")
    )

API:et för `Aggregate` är som följer:

class Aggregate(*expressions, output_field=None, distinct=False, filter=None, default=None, order_by=None, **extra)
  template

    Ett klassattribut, i form av en formatsträng, som beskriver den SQL som genereras för detta aggregat. Standardvärdet är `'%(function)s(%(distinct)s%(expressions)s)'`.

  function

    Ett klassattribut som beskriver den aggregerade funktion som ska genereras. Specifikt kommer `funktionen` att interpoleras som `funktion` platshållare inom `template`. Standardvärdet är `None`.

  window_compatible

    Standardvärdet är `True` eftersom de flesta aggregerade funktioner kan användas som källuttryck i `Window`.

  allow_distinct

    Ett klassattribut som avgör om denna aggregatfunktion tillåter att ett argument med nyckelordet `distinct` skickas eller inte. Om det är satt till `False` (standard), kommer `TypeError` att uppstå om `distinct=True` skickas.

  allow_order_by
    New in Django 6.0.

    A class attribute determining whether or not this aggregate function allows passing a `order_by` keyword argument. If set to `False` (default), `TypeError` is raised if `order_by` is passed as a value other than `None`.

  empty_result_set_value

    Standardvärdet är `None` eftersom de flesta aggregeringsfunktioner resulterar i `NULL` när de tillämpas på en tom resultatmängd.

De positionella argumenten `expressions` kan innehålla uttryck, transformationer av modellfältet eller namn på modellfält. De konverteras till en sträng och används som platshållare för `expressions` i `template`.

Argumentet `distinct` avgör om aggregatfunktionen ska anropas för varje distinkt värde i `expressions` (eller uppsättning värden, för flera `expressions`). Argumentet stöds endast av aggregat som har `allow_distinct` satt till `True`.

Argumentet `filter` tar ett `Q-objekt` som används för att filtrera de rader som aggregeras. Se Villkorlig aggregering och Filtrering av anteckningar för exempel på användning.

The `order_by` argument behaves similarly to the `field_names` input of the `order_by()` function, accepting a field name (with an optional `"-"` prefix which indicates descending order) or an expression (or a tuple or list of strings and/or expressions) that specifies the ordering of the elements in the result.

Argumentet `default` tar ett värde som kommer att skickas tillsammans med aggregatet till `Coalesce`. Detta är användbart för att ange ett annat värde som ska returneras än `None` när frågeuppsättningen (eller grupperingen) inte innehåller några poster.

De `**extra` kwargs är `nyckel=värde`-par som kan interpoleras in i `template`-attributet.

Changed in Django 6.0:

The `order_by` argument was added.

### Skapa dina egna aggregerade funktioner

Du kan också skapa dina egna aggregerade funktioner. Som ett minimum måste du definiera `function`, men du kan också helt anpassa den SQL som genereras. Här är ett kort exempel:

    from django.db.models import Aggregate

    class Sum(Aggregate):
        # Supports SUM(ALL field).
        function = "SUM"
        template = "%(function)s(%(all_values)s%(expressions)s)"
        allow_distinct = False
        arity = 1

        def __init__(self, expression, all_values=False, **extra):
            super().__init__(expression, all_values="ALL " if all_values else "", **extra)

### uttryck för `Value()`

class Value(value, output_field=None)

Ett `Value()`-objekt representerar den minsta möjliga komponenten i ett uttryck: ett enkelt värde. När du behöver representera värdet av ett heltal, en boolean eller en sträng i ett uttryck, kan du packa in värdet i ett `Value()`.

Du kommer sällan att behöva använda `Value()` direkt. När du skriver uttrycket `F('field') + 1` omsluter Django implicit `1` i en `Value()`, vilket gör att enkla värden kan användas i mer komplexa uttryck. Du kommer att behöva använda `Value()` när du vill skicka en sträng till ett uttryck. De flesta uttryck tolkar ett strängargument som namnet på ett fält, t.ex. `Lower('name')`.

Argumentet `value` beskriver det värde som ska ingå i uttrycket, t.ex. `1`, `True` eller `None`. Django vet hur man konverterar dessa Python-värden till deras motsvarande databastyp.

If no output_field is specified, it will be inferred from the type of the provided `value` for many common types. For example, passing an instance of `datetime.datetime` as `value` defaults `output_field` to `DateTimeField`.

### `ExpressionWrapper()` uttryck

class ExpressionWrapper(expression, output_field)

`ExpressionWrapper` omger ett annat uttryck och ger tillgång till egenskaper, t.ex. output_field, som kanske inte är tillgängliga för andra uttryck. `ExpressionWrapper` är nödvändig när man använder aritmetik på `F()`-uttryck med olika typer enligt beskrivningen i Använda F() med annotationer.

Database casting not performed

`ExpressionWrapper` only sets the output field for the ORM and does not perform any database-level casting. To ensure a specific type is returned from the database, use `Cast` instead.

### Villkorliga uttryck

Conditional expressions allow you to use `if` … `elif` … `else` logic in queries. Django natively supports SQL `CASE` expressions. For more details see Villkorliga uttryck.

### uttryck för `Subquery()`

class Subquery(queryset, output_field=None)

Du kan lägga till en explicit underfråga till en `QuerySet` med hjälp av uttrycket `Subquery`.

Till exempel: för att kommentera varje inlägg med e-postadressen till författaren till den nyaste kommentaren till det inlägget:

    >>> from django.db.models import OuterRef, Subquery
    >>> newest = Comment.objects.filter(post=OuterRef("pk")).order_by("-created_at")
    >>> Post.objects.annotate(newest_commenter_email=Subquery(newest.values("email")[:1]))

På PostgreSQL ser SQL ut som:

    SELECT "post"."id", (
        SELECT U0."email"
        FROM "comment" U0
        WHERE U0."post_id" = ("post"."id")
        ORDER BY U0."created_at" DESC LIMIT 1
    ) AS "newest_commenter_email" FROM "post"

Observera

Exemplen i detta avsnitt är utformade för att visa hur man tvingar Django att utföra en underfråga. I vissa fall kan det vara möjligt att skriva ett likvärdigt queryset som utför samma uppgift tydligare eller effektivare.

#### Hänvisning till kolumner från den yttre queryset

class OuterRef(field)

Använd `OuterRef` när en queryset i en `Subquery` behöver referera till ett fält från den yttre queryn eller dess transform. Det fungerar som ett `F`-uttryck förutom att kontrollen för att se om det hänvisar till ett giltigt fält inte görs förrän den yttre frågeuppsättningen har lösts upp.

Instanser av `OuterRef` kan användas tillsammans med nästlade instanser av `Subquery` för att hänvisa till en innehållande frågeuppsättning som inte är den omedelbara föräldern. Till exempel: skulle denna frågeuppsättning behöva vara inom ett nästlat par av `Subquery`-instanser för att lösas korrekt:

    >>> Book.objects.filter(author=OuterRef(OuterRef("pk")))

#### Begränsa en underfrågeställning till en enda kolumn

Det finns tillfällen då en enda kolumn måste returneras från en `Subquery`, t.ex. för att använda en `Subquery` som mål för en `__in`-uppslagning. För att returnera alla kommentarer för inlägg som publicerats under den senaste dagen:

    >>> from datetime import timedelta
    >>> from django.utils import timezone
    >>> one_day_ago = timezone.now() - timedelta(days=1)
    >>> posts = Post.objects.filter(published_at__gte=one_day_ago)
    >>> Comment.objects.filter(post__in=Subquery(posts.values("pk")))

I det här fallet måste underfrågan använda `values()` för att bara returnera en enda kolumn: inläggets primärnyckel.

#### Begränsa underfrågeställningen till en enda rad

För att förhindra att en underfråga returnerar flera rader används en del (`[:1]`) av frågeuppsättningen:

    >>> subquery = Subquery(newest.values("email")[:1])
    >>> Post.objects.annotate(newest_commenter_email=subquery)

I det här fallet får subquery bara returnera en enda kolumn och en enda rad: e-postadressen till den senast skapade kommentaren.

(Att använda `get()` istället för en slice skulle misslyckas eftersom `OuterRef` inte kan lösas förrän queryset används inom en `Subquery`)

#### `Existerar()` underfrågor

class Exists(queryset)

`Exists` är en `Subquery`-underklass som använder en SQL `EXISTS`-sats. I många fall kommer den att fungera bättre än en subquery eftersom databasen kan stoppa utvärderingen av subquery när en första matchande rad hittas.

Till exempel: för att markera varje inlägg med om det har en kommentar från den senaste dagen eller inte:

    >>> from django.db.models import Exists, OuterRef
    >>> from datetime import timedelta
    >>> from django.utils import timezone
    >>> one_day_ago = timezone.now() - timedelta(days=1)
    >>> recent_comments = Comment.objects.filter(
    ...     post=OuterRef("pk"),
    ...     created_at__gte=one_day_ago,
    ... )
    >>> Post.objects.annotate(recent_comment=Exists(recent_comments))

På PostgreSQL ser SQL ut som:

    SELECT "post"."id", "post"."published_at", EXISTS(
        SELECT (1) as "a"
        FROM "comment" U0
        WHERE (
            U0."created_at" >= YYYY-MM-DD HH:MM:SS AND
            U0."post_id" = "post"."id"
        )
        LIMIT 1
    ) AS "recent_comment" FROM "post"

Det är onödigt att tvinga `Exists` att hänvisa till en enda kolumn, eftersom kolumnerna kasseras och ett booleskt resultat returneras. På samma sätt, eftersom ordning är oviktigt inom en SQL `EXISTS` subquery och bara skulle försämra prestanda, tas det automatiskt bort.

Du kan ställa frågor med hjälp av `NOT EXISTS` med `~Exists()`.

#### Filtrering på ett `Subquery()`- eller `Exists()`-uttryck

`Subquery()` som returnerar ett booleskt värde och `Exists()` kan användas som ett `villkor` i `When`-uttryck, eller för att direkt filtrera en frågeuppsättning:

    >>> recent_comments = Comment.objects.filter(...)  # From above
    >>> Post.objects.filter(Exists(recent_comments))

Detta säkerställer att subquery inte läggs till i `SELECT`-kolumnerna, vilket kan leda till bättre prestanda.

#### Använda aggregat inom ett `Subquery`-uttryck

Aggregat kan användas i en `Subquery`, men de kräver en specifik kombination av `filter()`, `values()` och `annotate()` för att grupperingen av subquery ska bli korrekt.

Förutsatt att båda modellerna har ett `längd`-fält, för att hitta inlägg där inläggslängden är större än den totala längden på alla kombinerade kommentarer:

    >>> from django.db.models import OuterRef, Subquery, Sum
    >>> comments = Comment.objects.filter(post=OuterRef("pk")).order_by().values("post")
    >>> total_comments = comments.annotate(total=Sum("length")).values("total")
    >>> Post.objects.filter(length__gt=Subquery(total_comments))

Den inledande `filter(...)` begränsar underfrågan till de relevanta parametrarna. `order_by()` tar bort standard `ordering` (om någon) på `Comment`-modellen. `values('post')` aggregerar kommentarer efter `Post`. Slutligen utför `annotate(...)` aggregeringen. Den ordning i vilken dessa queryset-metoder tillämpas är viktig. I det här fallet, eftersom underfrågan måste begränsas till en enda kolumn, krävs `values('total')`.

Detta är det enda sättet att utföra en aggregering inom en `Subquery`, eftersom användning av `aggregate()` försöker utvärdera queryset (och om det finns en `OuterRef` kommer detta inte att vara möjligt att lösa).

### Råa SQL-uttryck

class RawSQL(sql, params, output_field=None)

Ibland kan databasuttryck inte enkelt uttrycka en komplex `WHERE` klausul. I dessa kantfall använder du `RawSQL` -uttrycket. Till exempel:

    >>> from django.db.models.expressions import RawSQL
    >>> queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (param,)))

Dessa extra uppslagningar kanske inte är portabla till olika databasmotorer (eftersom du uttryckligen skriver SQL-kod) och bryter mot DRY-principen, så du bör undvika dem om möjligt.

`RawSQL`-uttryck kan också användas som mål för `__in`-filter:

    >>> queryset.filter(id__in=RawSQL("select id from sometable where col = %s", (param,)))

Varning

För att skydda mot SQL injection attacks, måste du undkomma alla parametrar som användaren kan kontrollera genom att använda `params`. `params` är ett obligatoriskt argument för att tvinga dig att erkänna att du inte interpolerar din SQL med användartillhandahållna data.

Du får inte heller använda citattecken för platshållare i SQL-strängen. Det här exemplet är sårbart för SQL-injektion på grund av citaten runt `%s`:

    RawSQL("select col from sometable where othercol = '%s'")  # unsafe!

Du kan läsa mer om hur Djangos SQL injection protection fungerar.

### Fönsterfunktioner

Fönsterfunktioner är ett sätt att tillämpa funktioner på partitioner. Till skillnad från en vanlig aggregeringsfunktion som beräknar ett slutresultat för varje uppsättning som definieras av group by, arbetar fönsterfunktioner med ramar och partitioner och beräknar resultatet för varje rad.

Du kan ange flera fönster i samma fråga, vilket i Django ORM skulle motsvara att inkludera flera uttryck i ett QuerySet.annotate()-anrop. ORM använder sig inte av namngivna fönster, utan de är en del av de valda kolumnerna.

class Window(expression, partition_by=None, order_by=None, frame=None, output_field=None)
  template

    Standardvärdet är `%(expression)s OVER (%(window)s)`. Om endast argumentet `expression` anges, kommer window-satsen att vara tom.

Klassen `Window` är huvuduttrycket för en `OVER`-sats.

Argumentet `expression` är antingen en window function, en aggregate function, eller ett uttryck som är kompatibelt i en window clause.

The `partition_by` argument accepts an expression or a sequence of expressions (column names should be wrapped in an `F`-object) that control the partitioning of the rows. Partitioning narrows which rows are used to compute the result set.

output_field anges antingen som ett argument eller genom ett uttryck.

Argumentet `order_by` accepterar ett uttryck som du kan anropa `asc()` och `desc()`, en sträng med ett fältnamn (med ett valfritt prefix `"-"` som anger fallande ordning), eller en tupel eller lista med strängar och/eller uttryck. Ordningsföljden styr i vilken ordning uttrycket tillämpas. Om du t.ex. summerar över raderna i en partition är det första resultatet värdet på den första raden, det andra är summan av den första och den andra raden.

Parametern `frame` anger vilka andra rader som ska användas i beräkningen. Se Ramar för mer information.

Till exempel: för att kommentera varje film med det genomsnittliga betyget för filmer från samma studio i samma genre och utgivningsår:

    >>> from django.db.models import Avg, F, Window
    >>> Movie.objects.annotate(
    ...     avg_rating=Window(
    ...         expression=Avg("rating"),
    ...         partition_by=[F("studio"), F("genre")],
    ...         order_by="released__year",
    ...     ),
    ... )

Detta gör att du kan kontrollera om en film har fått bättre eller sämre betyg än sina konkurrenter.

Du kanske vill använda flera uttryck över samma fönster, dvs. samma partition och ram. Du kan t.ex. ändra det föregående exemplet så att det även inkluderar det bästa och sämsta betyget i varje filmgrupp (samma studio, genre och utgivningsår) genom att använda tre fönsterfunktioner i samma fråga. Partitionen och ordningen från föregående exempel extraheras till en ordbok för att minska upprepning:

    >>> from django.db.models import Avg, F, Max, Min, Window
    >>> window = {
    ...     "partition_by": [F("studio"), F("genre")],
    ...     "order_by": "released__year",
    ... }
    >>> Movie.objects.annotate(
    ...     avg_rating=Window(
    ...         expression=Avg("rating"),
    ...         **window,
    ...     ),
    ...     best=Window(
    ...         expression=Max("rating"),
    ...         **window,
    ...     ),
    ...     worst=Window(
    ...         expression=Min("rating"),
    ...         **window,
    ...     ),
    ... )

Filtrering mot fönsterfunktioner stöds så länge som uppslagningar inte är disjunktiva (inte använder `OR` eller `XOR` som en koppling) och mot en frågeuppsättning som utför aggregering.

Exempelvis stöds inte en fråga som bygger på aggregering och som har ett filter med `OR` mot en fönsterfunktion och ett fält. Om kombinerade predikat tillämpas efter aggregering kan det leda till att rader som normalt inte ingår i grupper inkluderas:

    >>> qs = Movie.objects.annotate(
    ...     category_rank=Window(Rank(), partition_by="category", order_by="-rating"),
    ...     scenes_count=Count("actors"),
    ... ).filter(Q(category_rank__lte=3) | Q(title__contains="Batman"))
    >>> list(qs)
    NotImplementedError: Heterogeneous disjunctive predicates against window functions
    are not implemented when performing conditional aggregation.

Bland Djangos inbyggda databasbackends stöder MySQL, PostgreSQL och Oracle fönsteruttryck. Stödet för olika funktioner i fönsteruttryck varierar mellan de olika databaserna. Till exempel: kanske alternativen i `asc()` och `desc()` inte stöds. Konsultera dokumentationen för din databas vid behov.

#### Ramar

För en fönsterram kan du välja antingen en intervallbaserad sekvens av rader eller en vanlig sekvens av rader.

class ValueRange(start=None, end=None, exclusion=None)
  frame_type

    Detta attribut är inställt på `'RANGE'`.

  PostgreSQL har begränsat stöd för `ValueRange` och stöder endast användning av standardstart- och slutpunkter, såsom `CURRENT ROW` och `UNBOUNDED FOLLOWING`.

class RowRange(start=None, end=None, exclusion=None)
  frame_type

    Detta attribut är inställt på `'ROWS'`.

Båda klasserna returnerar SQL med mallen:

    %(frame_type)s BETWEEN %(start)s AND %(end)s

class WindowFrameExclusion
  CURRENT_ROW
  GROUP
  TIES
  NO_OTHERS

Med argumentet `exclusion` kan du utesluta rader (`CURRENT_ROW`), grupper (`GROUP`) och band (`TIES`) från fönsterramarna i databaser som stöds:

    %(frame_type)s BETWEEN %(start)s AND %(end)s EXCLUDE %(exclusion)s

Ramar begränsar de rader som används för att beräkna resultatet. De flyttas från en viss startpunkt till en viss angiven slutpunkt. Ramar kan användas med eller utan partitioner, men det är ofta en bra idé att ange en ordning för fönstret för att säkerställa ett deterministiskt resultat. I en ram är en peer i en ram en rad med ett likvärdigt värde, eller alla rader om det inte finns någon ordningsbestämmelse.

Standardstartpunkten för en ram är `UNBOUNDED PRECEDING`, vilket är den första raden i partitionen. Slutpunkten inkluderas alltid explicit i den SQL som genereras av ORM och är som standard `UNBOUNDED FOLLOWING`. Standardramen omfattar alla rader från partitionen till den sista raden i uppsättningen.

De accepterade värdena för argumenten `start` och `end` är `None`, ett heltal eller noll. Ett negativt heltal för `start` resulterar i `N PRECEDING`, medan `None` ger `UNBOUNDED PRECEDING`. I läget `ROWS` kan ett positivt heltal användas för `start`, vilket resulterar i `N FOLLOWING`. Positiva heltal accepteras för `slut` och resulterar i `N FOLLOWING`. I läget `ROWS` kan ett negativt heltal användas för `end` vilket resulterar i `N PRECEDING`. För både `start` och `end` kommer noll att returnera `CURRENT ROW`.

Det finns en skillnad i vad `CURRENT ROW` inkluderar. När det anges i läget `ROWS` börjar eller slutar ramen med den aktuella raden. När den anges i läget `RANGE` startar eller slutar ramen vid den första eller sista peer enligt orderklausulen. Således utvärderar `RANGE CURRENT ROW` uttrycket för rader som har samma värde som specificeras av ordningsföljden. Eftersom mallen innehåller både `start`- och `slut`-punkter kan detta uttryckas med:

    ValueRange(start=0, end=0)

Om en films ”jämlikar” beskrivs som filmer som släppts av samma studio i samma genre under samma år, kommenterar detta `RowRange`-exempel varje film med det genomsnittliga betyget för filmens två föregående och två efterföljande jämlikar:

    >>> from django.db.models import Avg, F, RowRange, Window
    >>> Movie.objects.annotate(
    ...     avg_rating=Window(
    ...         expression=Avg("rating"),
    ...         partition_by=[F("studio"), F("genre")],
    ...         order_by="released__year",
    ...         frame=RowRange(start=-2, end=2),
    ...     ),
    ... )

Om databasen har stöd för det kan du ange start- och slutpunkter baserat på värden för ett uttryck i partitionen. Om fältet `released` i modellen `Movie` lagrar utgivningsmånaden för varje film, anger detta exempel på `ValueRange` för varje film det genomsnittliga betyget för andra filmer som släppts mellan tolv månader före och tolv månader efter varje film:

    >>> from django.db.models import Avg, F, ValueRange, Window
    >>> Movie.objects.annotate(
    ...     avg_rating=Window(
    ...         expression=Avg("rating"),
    ...         partition_by=[F("studio"), F("genre")],
    ...         order_by="released__year",
    ...         frame=ValueRange(start=-12, end=12),
    ...     ),
    ... )

## Teknisk information

Nedan hittar du tekniska implementeringsdetaljer som kan vara användbara för biblioteksförfattare. Det tekniska API:et och exemplen nedan hjälper till att skapa generiska frågeuttryck som kan utöka den inbyggda funktionaliteten som Django tillhandahåller.

### Uttryck API

Frågeuttryck implementerar query expression API, men exponerar också ett antal extra metoder och attribut som listas nedan. Alla frågeuttryck måste ärva från `Expression()` eller en relevant underklass.

När ett frågeuttryck omsluter ett annat uttryck är det ansvarigt för att anropa lämpliga metoder för det omslutna uttrycket.

class Expression
  allowed_default

    Talar om för Django att detta uttryck kan användas i `Field.db_default`. Standardvärdet är `False`.

  constraint_validation_compatible

    Talar om för Django att detta uttryck kan användas under en begränsningsvalidering. Uttryck med `constraint_validation_compatible` inställt på `False` får endast ha ett källuttryck. Standardvärdet är `True`.

  contains_aggregate

    Talar om för Django att detta uttryck innehåller ett aggregat och att en `GROUP BY`-klausul måste läggas till i frågan.

  contains_over_clause

    Talar om för Django att detta uttryck innehåller ett `Window`-uttryck. Det används till exempel för att inte tillåta fönsterfunktionsuttryck i frågor som modifierar data.

  filterable

    Talar om för Django att detta uttryck kan refereras till i `QuerySet.filter()`. Standardvärdet är `True`.

  window_compatible

    Talar om för Django att detta uttryck kan användas som källuttryck i `Window`. Standardvärdet är `False`.

  empty_result_set_value

    Tells Django which value should be returned when the expression is used to apply a function over an empty result set. Defaults to `NotImplemented` which forces the expression to be computed on the database.

  set_returning
    New in Django 5.2.

    Talar om för Django att detta uttryck innehåller en set-returneringsfunktion, vilket tvingar fram utvärdering av underfrågor. Det används t.ex. för att tillåta vissa Postgres set-returning-funktioner (t.ex. `JSONB_PATH_QUERY`, `UNNEST`, etc.) att hoppa över optimering och utvärderas korrekt när annotationer skapar rader själva. Standardvärde är `False`.

  allows_composite_expressions
    New in Django 5.2.

    Talar om för Django att detta uttryck tillåter sammansatta uttryck, till exempel för att stödja sammansatta primärnycklar. Standardvärdet är `False`.

  resolve_expression(query=None, allow_joins=True, reuse=None, summarize=False, for_save=False)

    Ger möjlighet att göra förbehandling eller validering av uttrycket innan det läggs till i frågan. `resolve_expression()` måste också anropas på alla nästlade uttryck. En `copy()` av `self` bör returneras med alla nödvändiga transformationer.

    `query` är implementeringen av backend-frågan.

    `allow_joins` är en boolean som tillåter eller förnekar användning av joins i frågan.

    `reuse` är en uppsättning återanvändbara joins för scenarier med flera joins.

    `summarize` är en boolean som, när den är `True`, signalerar att den fråga som beräknas är en terminal aggregerad fråga.

    `for_save` är en boolean som, när den är `True`, signalerar att den fråga som körs utför en skapelse eller uppdatering.

  get_source_expressions()

    Returnerar en ordnad lista med inre uttryck. Till exempel:

        >>> Sum(F("foo")).get_source_expressions()
        [F('foo')]

  set_source_expressions(expressions)

    Tar emot en lista med uttryck och lagrar dem så att `get_source_expressions()` kan returnera dem.

  relabeled_clone(change_map)

    Returnerar en klon (kopia) av `self`, med eventuella kolumnaliaser ommärkta. Kolumnaliaser byter namn när underförfrågningar skapas. `relabeled_clone()` bör också anropas på alla nästlade uttryck och tilldelas klonen.

    `change_map` är en ordlista som mappar gamla alias till nya alias.

    Exempel:

        def relabeled_clone(self, change_map):
            clone = copy.copy(self)
            clone.expression = self.expression.relabeled_clone(change_map)
            return clone

  convert_value(value, expression, connection)

    En hook som gör det möjligt för uttrycket att tvinga `värde` till en mer lämplig typ.

    `uttryck` är detsamma som `själv`.

  get_group_by_cols()

    Ansvarig för att returnera listan över kolumner som refereras av detta uttryck. `get_group_by_cols()` bör anropas på alla nästlade uttryck. i synnerhet `F()`-objekt innehåller en referens till en kolumn.

  asc(nulls_first=None, nulls_last=None)

    Returnerar det uttryck som är klart att sorteras i stigande ordning.

    `nulls_first` och `nulls_last` definierar hur null-värden sorteras. Se Använda F() för att sortera nollvärden för exempel på användning.

  desc(nulls_first=None, nulls_last=None)

    Returnerar det uttryck som är klart att sorteras i fallande ordning.

    `nulls_first` och `nulls_last` definierar hur null-värden sorteras. Se Använda F() för att sortera nollvärden för exempel på användning.

  reverse_ordering()

    Returns `self` with any modifications required to reverse the sort order within an `order_by` call. As an example, an expression implementing `NULLS LAST` would change its value to be `NULLS FIRST`. Modifications are only required for expressions that implement sort order like `OrderBy`. This method is called when `reverse()` is called on a queryset.

### Skriva dina egna frågeuttryck

Du kan skriva dina egna query expression-klasser som använder och kan integreras med andra query expressions. Låt oss gå igenom ett exempel genom att skriva en implementation av SQL-funktionen `COALESCE`, utan att använda de inbyggda Func()-uttrycken.

SQL-funktionen `COALESCE` definieras som att den tar en lista med kolumner eller värden. Den returnerar den första kolumnen eller värdet som inte är `NULL`.

Vi börjar med att definiera den mall som ska användas för SQL-generering och en `__init__()`-metod för att ställa in några attribut:

    from django.db.models import Expression

    class Coalesce(Expression):
        template = "COALESCE( %(expressions)s )"

        def __init__(self, expressions, output_field):
            super().__init__(output_field=output_field)
            if len(expressions) < 2:
                raise ValueError("expressions must have at least 2 elements")
            for expression in expressions:
                if not hasattr(expression, "resolve_expression"):
                    raise TypeError("%r is not an Expression" % expression)
            self.expressions = expressions

Vi gör en del grundläggande validering av parametrarna, inklusive att kräva minst 2 kolumner eller värden och säkerställa att de är uttryck. Vi kräver output_field här så att Django vet vilken typ av modellfält som ska tilldelas det slutliga resultatet.

Nu implementerar vi förbehandling och validering. Eftersom vi inte har någon egen validering vid denna tidpunkt delegerar vi till de nästlade uttrycken:

    def resolve_expression(
        self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
    ):
        c = self.copy()
        c.is_summary = summarize
        for pos, expression in enumerate(self.expressions):
            c.expressions[pos] = expression.resolve_expression(
                query, allow_joins, reuse, summarize, for_save
            )
        return c

Därefter skriver vi den metod som ansvarar för att generera SQL:

    def as_sql(self, compiler, connection, template=None):
        sql_expressions, sql_params = [], []
        for expression in self.expressions:
            sql, params = compiler.compile(expression)
            sql_expressions.append(sql)
            sql_params.extend(params)
        template = template or self.template
        data = {"expressions": ",".join(sql_expressions)}
        return template % data, tuple(sql_params)

    def as_oracle(self, compiler, connection):
        """
        Example of vendor specific handling (Oracle in this case).
        Let's make the function name lowercase.
        """
        return self.as_sql(compiler, connection, template="coalesce( %(expressions)s )")

metoderna `as_sql()` kan stödja anpassade nyckelordsargument, vilket gör att metoderna `as_vendorname()` kan åsidosätta data som används för att generera SQL-strängen. Att använda `as_sql()` nyckelordsargument för anpassning är att föredra framför att mutera `self` inom `as_vendorname()`-metoder eftersom det senare kan leda till fel när det körs på olika databasbackends. Om din klass förlitar sig på klassattribut för att definiera data, överväg att tillåta åsidosättningar i din `as_sql()`-metod.

Vi genererar SQL för vart och ett av `uttrycken` med hjälp av metoden `compiler.compile()` och sammanfogar resultatet med kommatecken. Sedan fylls mallen i med våra data och SQL och parametrar returneras.

Vi har också definierat en anpassad implementering som är specifik för Oracle-backend. Funktionen `as_oracle()` kommer att anropas istället för `as_sql()` om Oracle-backend används.

Slutligen implementerar vi resten av de metoder som gör att vårt frågeuttryck kan fungera bra tillsammans med andra frågeuttryck:

    def get_source_expressions(self):
        return self.expressions

    def set_source_expressions(self, expressions):
        self.expressions = expressions

Låt oss se hur det fungerar:

    >>> from django.db.models import F, Value, CharField
    >>> qs = Company.objects.annotate(
    ...     tagline=Coalesce(
    ...         [F("motto"), F("ticker_name"), F("description"), Value("No Tagline")],
    ...         output_field=CharField(),
    ...     )
    ... )
    >>> for c in qs:
    ...     print("%s: %s" % (c.name, c.tagline))
    ...
    Google: Do No Evil
    Apple: AAPL
    Yahoo: Internet Company
    Django Software Foundation: No Tagline

#### Undvika SQL-injektion

Eftersom nyckelordsargumenten i en `Func` för `__init__()` (`**extra`) och `as_sql()` (`**extra_context`) interpoleras in i SQL-strängen i stället för att skickas som frågeparametrar (där databasdrivrutinen skulle undkomma dem), får de inte innehålla otillförlitlig användarinmatning.

Om till exempel `substring` är användartillhandahållen, är denna funktion sårbar för SQL-injektion:

    from django.db.models import Func

    class Position(Func):
        function = "POSITION"
        template = "%(function)s('%(substring)s' in %(expressions)s)"

        def __init__(self, expression, substring):
            # substring=substring is an SQL injection vulnerability!
            super().__init__(expression, substring=substring)

Denna funktion genererar en SQL-sträng utan några parametrar. Eftersom `substring` skickas till `super().__init__()` som ett nyckelordsargument, interpoleras det till SQL-strängen innan frågan skickas till databasen.

Här är en korrigerad omskrivning:

    class Position(Func):
        function = "POSITION"
        arg_joiner = " IN "

        def __init__(self, expression, substring):
            super().__init__(substring, expression)

Om `substring` istället skickas som ett positionellt argument kommer det att skickas som en parameter i databasfrågan.

### Lägga till stöd för databasbackends från tredje part

Om du använder en databasbackend som använder en annan SQL-syntax för en viss funktion kan du lägga till stöd för den genom att apa till en ny metod till funktionens klass.

Låt oss säga att vi skriver en backend för Microsofts SQL Server som använder SQL `LEN` istället för `LENGTH` för funktionen `Length`. Vi kommer att apa patch en ny metod som heter `as_sqlserver()` på klassen `Length`:

    from django.db.models.functions import Length

    def sqlserver_length(self, compiler, connection):
        return self.as_sql(compiler, connection, function="LEN")

    Length.as_sqlserver = sqlserver_length

Du kan också anpassa SQL genom att använda parametern `template` i `as_sql()`.

Vi använder `as_sqlserver()` eftersom `django.db.connection.vendor` returnerar `sqlserver` för backend.

Tredjeparts backends kan registrera sina funktioner i toppnivån `__init__.py`-filen i backend-paketet eller i en toppnivå `expressions.py`-fil (eller paket) som importeras från toppnivån `__init__.py`.

För användarprojekt som vill patcha den backend som de använder bör den här koden finnas i en `AppConfig.ready()`-metod.