---
title: "Frågeuttryck"
version: 5.2
locale: sv
source: https://docs.djangoproject.com/sv/5.2/ref/models/expressions/
canonical: https://djangodocs.dev/sv/5.2/ref/models/expressions/
---
# 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](/sv/5.2/howto/custom-model-fields/).

## Några exempel

```pycon
>>> 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")))
# Be sure to refresh it if you need to access the field.
>>> company.refresh_from_db()
>>> 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

> **Note**
>
> 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`](/sv/5.2/topics/db/models/#module-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.

För att komma åt det nya värdet som sparats på detta sätt måste objektet laddas om:

```
reporter = Reporters.objects.get(pk=reporter.pk)
# Or, more succinctly:
reporter.refresh_from_db()
```

Förutom att användas i operationer på enskilda instanser som ovan, kan `F()` användas med `update()` för att utföra massuppdateringar på en `QuerySet`. Detta reducerar de två frågor vi använde ovan - `get()` och [`save()`](/sv/5.2/ref/models/instances/#django.db.models.Model.save) \- till bara en:

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

Vi kan också använda [`update()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.update) för att öka fältvärdet på flera objekt - vilket kan vara mycket snabbare än att hämta dem alla till Python från databasen, loopa över dem, öka fältvärdet för var och en och spara var och en tillbaka till databasen:

```
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

> **New in Django 5.1**

För strängbaserade fält, textbaserade fält och [`ArrayField`](/sv/5.2/ref/contrib/postgres/fields/#django.contrib.postgres.fields.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:

```pycon
>>> # Replacing a name with a substring of itself.
>>> writer = Writers.objects.get(name="Priyansh")
>>> writer.name = F("name")[1:5]
>>> writer.save()
>>> writer.refresh_from_db()
>>> 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.

Om databasen ansvarar för uppdateringen av fältet är processen mer robust: fältet kommer bara att uppdateras baserat på fältets värde i databasen när [`save()`](/sv/5.2/ref/models/instances/#django.db.models.Model.save) eller `update()` körs, snarare än baserat på dess värde när instansen hämtades.

#### `F()`-uppdrag kvarstår efter `Model.save()`

`F()`-objekt som tilldelats modellfält kvarstår efter att modellinstansen sparats och kommer att tillämpas på varje [`save()`](/sv/5.2/ref/models/instances/#django.db.models.Model.save). Till exempel:

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

reporter.name = "Tintin Jr."
reporter.save()
```

`stories_filed` kommer att uppdateras två gånger i det här fallet. Om det ursprungligen är `1` kommer det slutliga värdet att vara `3`. Denna persistens kan undvikas genom att ladda om modellobjektet efter att det har sparats, till exempel genom att använda [`refresh_from_db()`](/sv/5.2/ref/models/instances/#django.db.models.Model.refresh_from_db).

#### 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](/sv/5.2/topics/db/queries/#using-f-expressions-in-filters).

#### 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](#output-field) för detta fall, men eftersom `F()` inte gör det, måste du omsluta uttrycket med [`ExpressionWrapper`](#django.db.models.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:

```pycon
>>> 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()`](#django.db.models.Expression.asc) eller [`desc()`](#django.db.models.Expression.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:

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

Se [Databasfunktioner](/sv/5.2/ref/models/database-functions/) för en lista över inbyggda databasfunktioner.

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`](#django.db.models.Func.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`*

```python
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](#avoiding-sql-injection-in-query-expressions) 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](#avoiding-sql-injection-in-query-expressions) 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](#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](#func-expressions) som informerar frågan om att en `GROUP BY`-klausul krävs. Alla [aggregate-funktioner](/sv/5.2/ref/models/querysets/#aggregation-functions), 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, **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`](#django.db.models.Aggregate.template). Standardvärdet är `None`.

#### `window_compatible`

Standardvärdet är `True` eftersom de flesta aggregerade funktioner kan användas som källuttryck i [`Window`](#django.db.models.expressions.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.

#### `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`](#django.db.models.Aggregate.allow_distinct) satt till `True`.

Argumentet `filter` tar ett [`Q-objekt`](/sv/5.2/ref/models/querysets/#django.db.models.Q) som används för att filtrera de rader som aggregeras. Se [Villkorlig aggregering](/sv/5.2/ref/models/conditional-expressions/#conditional-aggregation) och [Filtrering av anteckningar](/sv/5.2/topics/db/aggregation/#filtering-on-annotations) för exempel på användning.

Argumentet `default` tar ett värde som kommer att skickas tillsammans med aggregatet till [`Coalesce`](/sv/5.2/ref/models/database-functions/#django.db.models.functions.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.

### 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.

Om ingen output\_field\<output-field\>\` anges, kommer den att härledas från typen av det angivna `värdet` för många vanliga typer. Om du till exempel skickar en instans av [`datetime.datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) som `value` blir standardvärdet för `output_field` [`DateTimeField`](/sv/5.2/ref/models/fields/#django.db.models.DateTimeField).

### `ExpressionWrapper()` uttryck

#### `class ExpressionWrapper(expression, output_field)`

`ExpressionWrapper` omger ett annat uttryck och ger tillgång till egenskaper, t.ex. [output\_field](#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](#using-f-with-annotations).

> **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`](/sv/5.2/ref/models/database-functions/#django.db.models.functions.Cast) instead.

### Villkorliga uttryck

Med villkorliga uttryck kan du använda [`if`](https://docs.python.org/3/reference/compound_stmts.html#if) … [`elif`](https://docs.python.org/3/reference/compound_stmts.html#elif) … [`else`](https://docs.python.org/3/reference/compound_stmts.html#else) logik i frågor. Django har inbyggt stöd för SQL `CASE` uttryck. För mer detaljer se [Villkorliga uttryck](/sv/5.2/ref/models/conditional-expressions/).

### 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:

```pycon
>>> 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:

```sql
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"
```

> **Note**
>
> 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`](#django.db.models.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:

```pycon
>>> 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:

```pycon
>>> 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()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.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:

```pycon
>>> 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()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.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:

```pycon
>>> 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:

```sql
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`](/sv/5.2/ref/models/conditional-expressions/#django.db.models.expressions.When)-uttryck, eller för att direkt filtrera en frågeuppsättning:

```pycon
>>> 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()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.filter), [`values()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.values) och [`annotate()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.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:

```pycon
>>> 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`](/sv/5.2/ref/models/options/#django.db.models.Options.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()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.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:

```pycon
>>> 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:

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

> **Warning**
>
> För att skydda mot [SQL injection attacks](https://en.wikipedia.org/wiki/SQL_injection), 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](/sv/5.2/topics/security/#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](#window-frames) 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()](/sv/5.2/topics/db/aggregation/)-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](/sv/5.2/ref/models/database-functions/#window-functions), en [aggregate function](/sv/5.2/ref/models/querysets/#aggregation-functions), eller ett uttryck som är kompatibelt i en window clause.

Argumentet `partition_by` accepterar ett uttryck eller en sekvens av uttryck (kolumnnamnen bör vara inkapslade i ett `F`-objekt) som styr partitioneringen av raderna.  Partitioneringen begränsar vilka rader som används för att beräkna resultatuppsättningen.

[output\_field](#output-field) anges antingen som ett argument eller genom ett uttryck.

Argumentet `order_by` accepterar ett uttryck som du kan anropa [`asc()`](#django.db.models.Expression.asc) och [`desc()`](#django.db.models.Expression.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](#window-frames) 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:

```pycon
>>> 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:

```pycon
>>> 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:

```pycon
>>> 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()`](#django.db.models.Expression.asc) och [`desc()`](#django.db.models.Expression.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`.

> **Changed in Django 5.1**
>
> Argumentet `exkludering` har lagts till.

#### `class RowRange(start=None, end=None, exclusion=None)`

#### `frame_type`

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

> **Changed in Django 5.1**
>
> Argumentet `exkludering` har lagts till.

Båda klasserna returnerar SQL med mallen:

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

#### `class WindowFrameExclusion`

> **New in Django 5.1**

#### `CURRENT_ROW`

#### `GROUP`

#### `TIES`

#### `NO_OTHERS`

Med argumentet `exclusion` kan du utesluta rader ([`CURRENT_ROW`](#django.db.models.expressions.WindowFrameExclusion.CURRENT_ROW)), grupper ([`GROUP`](#django.db.models.expressions.WindowFrameExclusion.GROUP)) och band ([`TIES`](#django.db.models.expressions.WindowFrameExclusion.TIES)) från fönsterramarna i databaser som stöds:

```sql
%(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:

```pycon
>>> 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:

```pycon
>>> 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),
...     ),
... )
```

> **Changed in Django 5.1**
>
> Stöd för positivt heltal `start` och negativt heltal `slut` har lagts till för `RowRange`.

## 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](/sv/5.2/ref/models/lookups/#query-expression), 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`](/sv/5.2/ref/models/fields/#django.db.models.Field.db_default). Standardvärdet är `False`.

#### `constraint_validation_compatible`

> **New in Django 5.1**

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`](#django.db.models.expressions.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()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.filter). Standardvärdet är `True`.

#### `window_compatible`

Talar om för Django att detta uttryck kan användas som källuttryck i [`Window`](#django.db.models.expressions.Window). Standardvärdet är `False`.

#### `empty_result_set_value`

Talar om för Django vilket värde som ska returneras när uttrycket används för att tillämpa en funktion över en tom resultatmängd. Standardvärdet är [`NotImplemented`](https://docs.python.org/3/library/constants.html#NotImplemented) vilket tvingar uttrycket att beräknas i databasen.

#### `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](/sv/5.2/topics/composite-primary-key/#cpk-and-database-functions). 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:

```pycon
>>> 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](#using-f-to-sort-null-values) 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](#using-f-to-sort-null-values) för exempel på användning.

#### `reverse_ordering()`

Returnerar `self` med alla ändringar som krävs för att vända sorteringsordningen i ett `order_by`-anrop. Som ett exempel, ett uttryck som implementerar `NULLS LAST` skulle ändra sitt värde till `NULLS FIRST`. Modifieringar krävs endast för uttryck som implementerar sorteringsordning som `OrderBy`. Denna metod anropas när [`reverse()`](/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet.reverse) anropas på en 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](#func-expressions).

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](#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, 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:

```pycon
>>> 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`](/sv/5.2/ref/models/database-functions/#django.db.models.functions.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()`](/sv/5.2/ref/applications/#django.apps.AppConfig.ready)-metod.
