# Django 6.0.5 documentation

# Göra förfrågningar

När du har skapat dina datamodeller ger Django dig automatiskt ett API för databasabstraktion som låter dig skapa, hämta, uppdatera och radera objekt. Detta dokument förklarar hur man använder detta API. Se data model reference för fullständig information om alla de olika alternativen för modelluppslagning.

I den här handboken (och i referensen) hänvisar vi till följande modeller, som utgör en bloggapplikation:

    from datetime import date

    from django.db import models

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def __str__(self):
            return self.name

    class Author(models.Model):
        name = models.CharField(max_length=200)
        email = models.EmailField()

        def __str__(self):
            return self.name

    class Entry(models.Model):
        blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
        headline = models.CharField(max_length=255)
        body_text = models.TextField()
        pub_date = models.DateField()
        mod_date = models.DateField(default=date.today)
        authors = models.ManyToManyField(Author)
        number_of_comments = models.IntegerField(default=0)
        number_of_pingbacks = models.IntegerField(default=0)
        rating = models.IntegerField(default=5)

        def __str__(self):
            return self.headline

## Skapa objekt

För att representera databastabelldata i Python-objekt använder Django ett intuitivt system: En modellklass representerar en databastabell, och en instans av den klassen representerar en viss post i databastabellen.

För att skapa ett objekt, instansiera det med hjälp av nyckelordsargument till modellklassen och anropa sedan `save()` för att spara det i databasen.

Förutsatt att modellerna finns i filen `models.py` i en Django-app med namnet `blog`, följer här ett exempel:

    >>> from blog.models import Blog
    >>> b = Blog(name="Beatles Blog", tagline="All the latest Beatles news.")
    >>> b.save()

Detta utför en `INSERT` SQL-sats bakom kulisserna. Django träffar inte databasen förrän du uttryckligen anropar `save()`.

Metoden `save()` har inget returvärde.

Se även

`save()` har ett antal avancerade alternativ som inte beskrivs här. Se dokumentationen för `save()` för fullständig information.

To create and save an object in a single step, use the `create()` method.

## Spara ändringar av objekt

Om du vill spara ändringar i ett objekt som redan finns i databasen använder du `save()`.

Med en `Blog`-instans `b5` som redan har sparats i databasen ändrar detta exempel dess namn och uppdaterar dess post i databasen:

    >>> b5.name = "New name"
    >>> b5.save()

Detta utför en `UPDATE` SQL-sats bakom kulisserna. Django träffar inte databasen förrän du uttryckligen anropar `save()`.

### Spara fälten `ForeignKey` och `ManyToManyField`

Uppdatering av ett `ForeignKey`-fält fungerar exakt på samma sätt som att spara ett vanligt fält - tilldela ett objekt av rätt typ till fältet i fråga. Detta exempel uppdaterar attributet `blog` för en `Entry`-instans `entry`, förutsatt att lämpliga instanser av `Entry` och `Blog` redan har sparats i databasen (så att vi kan hämta dem nedan):

    >>> from blog.models import Blog, Entry
    >>> entry = Entry.objects.get(pk=1)
    >>> cheese_blog = Blog.objects.get(name="Cheddar Talk")
    >>> entry.blog = cheese_blog
    >>> entry.save()

Uppdatering av en `ManyToManyField` fungerar lite annorlunda - använd metoden `add()` på fältet för att lägga till en post i relationen. Detta exempel lägger till `Author`-instansen `joe` till `entry`-objektet:

    >>> from blog.models import Author
    >>> joe = Author.objects.create(name="Joe")
    >>> entry.authors.add(joe)

För att lägga till flera poster till en `ManyToManyField` på en gång, inkludera flera argument i anropet till `add()`, så här:

    >>> john = Author.objects.create(name="John")
    >>> paul = Author.objects.create(name="Paul")
    >>> george = Author.objects.create(name="George")
    >>> ringo = Author.objects.create(name="Ringo")
    >>> entry.authors.add(john, paul, george, ringo)

Django kommer att klaga om du försöker tilldela eller lägga till ett objekt av fel typ.

## Hämta objekt

För att hämta objekt från din databas, konstruera en `QuerySet` via en `Manager` på din modellklass.

En `QuerySet` representerar en samling objekt från din databas. Den kan ha noll, ett eller många filter. Filter begränsar frågeresultaten baserat på de angivna parametrarna. I SQL-termer motsvarar en `QuerySet` en `SELECT`-sats, och ett filter är en begränsningsklausul som `WHERE` eller `LIMIT`.

Du får en `QuerySet` genom att använda din modells `Manager`. Varje modell har minst en `Manager`, och den kallas `objects` som standard. Du kan komma åt den direkt via modellklassen, så här:

    >>> Blog.objects
    <django.db.models.manager.Manager object at ...>
    >>> b = Blog(name="Foo", tagline="Bar")
    >>> b.objects
    Traceback:
        ...
    AttributeError: "Manager isn't accessible via Blog instances."

Observera

En `Manager` är endast tillgänglig via modellklasser, snarare än från modellinstanser, för att upprätthålla en åtskillnad mellan operationer på ”tabellnivå” och operationer på ”postnivå”.

`Manager` är den huvudsakliga källan till querysets för en modell. Till exempel returnerar `Blog.objects.all()` en `QuerySet` som innehåller alla `Blog`-objekt i databasen.

### Hämta alla objekt

Det enklaste sättet att hämta objekt från en tabell är att hämta dem alla. För att göra detta använder du metoden `all()` på en `Manager`:

    >>> all_entries = Entry.objects.all()

Metoden `all()` returnerar en `QuerySet` av alla objekt i databasen.

### Hämta specifika objekt med filter

Den `QuerySet` som returneras av `all()` beskriver alla objekt i databastabellen. Vanligtvis behöver du dock bara välja en delmängd av den fullständiga uppsättningen objekt.

För att skapa en sådan delmängd förfinar du den ursprungliga `QuerySet` genom att lägga till filtervillkor. De två vanligaste sätten att förfina en `QuerySet` är:

`filter(**kwargs)`

  Returnerar en ny `QuerySet` som innehåller objekt som matchar de angivna uppslagsparametrarna.

`exkludera(**kwargs)`

  Returnerar en ny `QuerySet` som innehåller objekt som inte matchar de angivna uppslagsparametrarna.

Uppslagsparametrarna (`**kwargs` i ovanstående funktionsdefinitioner) ska vara i det format som beskrivs i Field lookups nedan.

Om du till exempel vill få en `QuerySet` med bloggposter från år 2006 använder du `filter()` så här:

    Entry.objects.filter(pub_date__year=2006)

Med den förvalda managerklassen är det samma sak som:

    Entry.objects.all().filter(pub_date__year=2006)

#### Kedja filter

Resultatet av att förfina en `QuerySet` är i sig en `QuerySet`, så det är möjligt att kedja förfiningar tillsammans. Till exempel:

    >>> Entry.objects.filter(headline__startswith="What").exclude(
    ...     pub_date__gte=datetime.date.today()
    ... ).filter(pub_date__gte=datetime.date(2005, 1, 30))

Detta tar den ursprungliga `QuerySet` av alla poster i databasen, lägger till ett filter, sedan en uteslutning, sedan ytterligare ett filter. Slutresultatet är en `QuerySet` som innehåller alla poster med en rubrik som börjar med ”What”, som publicerades mellan den 30 januari 2005 och den aktuella dagen.

#### Filtrerade `QuerySet` är unika

Varje gång du förfinar en `QuerySet` får du en helt ny `QuerySet` som inte på något sätt är bunden till den tidigare `QuerySet`. Varje förfining skapar en separat och distinkt `QuerySet` som kan lagras, användas och återanvändas.

Exempel:

    >>> q1 = Entry.objects.filter(headline__startswith="What")
    >>> q2 = q1.exclude(pub_date__gte=datetime.date.today())
    >>> q3 = q1.filter(pub_date__gte=datetime.date.today())

Dessa tre querysets är separata. Den första är en bas `QuerySet` som innehåller alla poster som innehåller en rubrik som börjar med ”What”. Den andra är en delmängd av den första, med ett ytterligare kriterium som utesluter poster vars `pub_date` är idag eller i framtiden. Den tredje är en delmängd av den första, med ett ytterligare kriterium som endast väljer poster vars `pub_date` är idag eller i framtiden. Den ursprungliga `QuerySet` (`q1`) påverkas inte av förfiningsprocessen.

#### ”QuerySet”: ”De är lata

`QuerySet`-objekt är lata - handlingen att skapa en `QuerySet` involverar inte någon databasaktivitet. Du kan stapla filter tillsammans hela dagen, och Django kommer faktiskt inte att köra frågan förrän `QuerySet` är utvärderad. Ta en titt på detta exempel:

    >>> q = Entry.objects.filter(headline__startswith="What")
    >>> q = q.filter(pub_date__lte=datetime.date.today())
    >>> q = q.exclude(body_text__icontains="food")
    >>> print(q)

Även om det här ser ut som tre träffar i databasen, träffar den i själva verket databasen bara en gång, på den sista raden (`print(q)`). I allmänhet hämtas inte resultaten från en `QuerySet` från databasen förrän du ”ber” om dem. När du gör det utvärderas `QuerySet` genom att komma åt databasen. För mer information om exakt när utvärderingen sker, se När QuerySet utvärderas.

### Hämta ett enskilt objekt med `get()`

`filter()` ger dig alltid en `QuerySet`, även om bara ett enda objekt matchar frågan - i det här fallet kommer det att vara en `QuerySet` som innehåller ett enda element.

Om du vet att det bara finns ett objekt som matchar din fråga kan du använda metoden `get()` på en `Manager` som returnerar objektet direkt:

    >>> one_entry = Entry.objects.get(pk=1)

Du kan använda vilket frågeuttryck som helst med `get()`, precis som med `filter()` - se Fältuppslagningar nedan.

Observera att det är skillnad mellan att använda `get()` och att använda `filter()` med en slice av `[0]`. Om det inte finns några resultat som matchar frågan kommer `get()` att ge upphov till ett `DoesNotExist` undantag. Detta undantag är ett attribut för den modellklass som frågan utförs på - så i koden ovan, om det inte finns något `Entry`-objekt med en primärnyckel på 1, kommer Django att höja `Entry.DoesNotExist`.

På samma sätt kommer Django att klaga om mer än ett objekt matchar `get()`-frågan. I det här fallet kommer det att höja `MultipleObjectsReturned`, vilket återigen är ett attribut för själva modellklassen.

### Andra metoder för `QuerySet`

För det mesta använder du `all()`, `get()`, `filter()` och `exclude()` när du behöver leta upp objekt från databasen. Men det är långt ifrån allt som finns; se QuerySet API Reference för en fullständig lista över alla olika `QuerySet`-metoder.

### Begränsning av `QuerySet`

Använd en delmängd av Pythons array-slicing-syntax för att begränsa din `QuerySet` till ett visst antal resultat. Detta är motsvarigheten till SQL:s `LIMIT` och `OFFSET`-klausuler.

Till exempel returneras de 5 första objekten (`LIMIT 5`):

    >>> Entry.objects.all()[:5]

Detta returnerar det sjätte till det tionde objektet (`OFFSET 5 LIMIT 5`):

    >>> Entry.objects.all()[5:10]

Negativ indexering (t.ex. `Entry.objects.all()[-1]`) stöds inte.

Generellt sett returnerar skivning av en `QuerySet` en ny `QuerySet` – den utvärderar inte frågan. Ett undantag är om du använder parametern ”step” i Pythons slice-syntax. Till exempel skulle detta faktiskt utföra frågan för att returnera en lista över varje andra objekt av de första 10:

    >>> Entry.objects.all()[:10:2]

Ytterligare filtrering eller ordning av en skivad frågeuppsättning är förbjuden på grund av den tvetydiga karaktären hos hur det kan fungera.

Om du vill hämta ett enkelt objekt i stället för en lista (t.ex. `SELECT foo FROM bar LIMIT 1`) använder du ett index i stället för en slice. Till exempel returnerar detta den första `Entry` i databasen, efter att ha ordnat posterna alfabetiskt efter rubrik:

    >>> Entry.objects.order_by("headline")[0]

Detta motsvarar ungefär:

    >>> Entry.objects.order_by("headline")[0:1].get()

Observera dock att den första av dessa kommer att ge upphov till `IndexError` medan den andra kommer att ge upphov till `DoesNotExist` om inga objekt matchar de angivna kriterierna. Se `get()` för mer information.

### Fältuppslagningar

Fältuppslagningar är hur du anger köttet i en SQL `WHERE`-klausul. De anges som nyckelordsargument till `QuerySet`-metoderna `filter()`, `exclude()` och `get()`.

Argument för nyckelord i Basic Lookups har formen `field__lookuptype=value`. (Det är en dubbel-underscore). Till exempel:

    >>> Entry.objects.filter(pub_date__lte="2006-01-01")

översätts (ungefär) till följande SQL:

    SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';

Hur detta är möjligt

Python har möjlighet att definiera funktioner som accepterar godtyckliga namn-värde-argument vars namn och värden utvärderas vid körning. För mer information, se Keyword Arguments i den officiella Python-handledningen.

Fältet som anges i en lookup måste vara namnet på ett modellfält. Det finns dock ett undantag, i händelse av en `ForeignKey` kan du ange fältnamnet suffixerat med `_id`. I det här fallet förväntas parametern value innehålla råvärdet för den utländska modellens primärnyckel. Till exempel:

    >>> Entry.objects.filter(blog_id=4)

Om du skickar ett ogiltigt nyckelordsargument kommer en lookup-funktion att ge upphov till `TypeError`.

Databasens API stöder ungefär två dussin uppslagstyper; en fullständig referens finns i field lookup reference. För att ge dig en försmak av vad som finns tillgängligt, här är några av de vanligaste uppslagningarna du förmodligen kommer att använda:

`exakt`

  En ”exakt” matchning. Till exempel:

      >>> Entry.objects.get(headline__exact="Cat bites dog")

  Skulle generera SQL enligt dessa linjer:

      SELECT ... WHERE headline = 'Cat bites dog';

  Om du inte anger någon uppslagstyp - det vill säga om ditt nyckelordsargument inte innehåller ett dubbelt understreck - antas uppslagstypen vara ”exakt”.

  Till exempel är följande två påståenden likvärdiga:

      >>> Blog.objects.get(id__exact=14)  # Explicit form
      >>> Blog.objects.get(id=14)  # __exact is implied

  Detta är för enkelhetens skull, eftersom `exakta` uppslagningar är det vanliga fallet.

`iexact`

  En matchning utan skiftlägeskänslighet. Så, frågan:

      >>> Blog.objects.get(name__iexact="beatles blog")

  Skulle matcha en `Blogg` med titeln `"Beatles Blog"`, `"beatles blog"`, eller till och med `"BeAtlES blOG"`.

`innehåller`

  Test med skiftlägeskänslighet. Till exempel:

      Entry.objects.get(headline__contains="Lennon")

  Översätts ungefär till denna SQL:

      SELECT ... WHERE headline LIKE '%Lennon%';

  Observera att detta kommer att matcha rubriken `'Today Lennon honored'` men inte `'today lennon honored'`.

  Det finns också en version som inte tar hänsyn till skiftlägeskod, `icontains`.

`startarmed`, `slutarmed`

  Börjar med respektive slutar med sökning. Det finns också versioner utan skiftlägeskänslighet som heter `istartswith` och `iendswith`.

Återigen, detta skrapar bara på ytan. En fullständig referens finns i field lookup reference.

### Uppslagningar som sträcker sig över relationer

Django erbjuder ett kraftfullt och intuitivt sätt att ”följa” relationer i uppslagningar, och tar hand om SQL `JOIN` åt dig automatiskt, bakom kulisserna. För att spänna över en relation använder du fältnamnet på relaterade fält i olika modeller, separerade med dubbla understreck, tills du kommer till det fält du vill ha.

Detta exempel hämtar alla `Entry`-objekt med en `Blog` vars `namn` är `'Beatles Blog'`:

    >>> Entry.objects.filter(blog__name="Beatles Blog")

Denna spänning kan vara så djup som du vill.

Det fungerar också baklänges. Även om det `kan anpassas`, hänvisar du som standard till ett ”omvänt” förhållande i en uppslagning med hjälp av modellens gemena namn.

Detta exempel hämtar alla `Blog` objekt som har minst en `Entry` vars `headline` innehåller `'Lennon'`:

    >>> Blog.objects.filter(entry__headline__contains="Lennon")

Om du filtrerar över flera relationer och en av de mellanliggande modellerna inte har ett värde som uppfyller filtervillkoret, kommer Django att behandla det som om det finns ett tomt (alla värden är `NULL`), men giltigt, objekt där. Allt detta innebär är att inget fel kommer att uppstå. Till exempel i detta filter:

    Blog.objects.filter(entry__authors__name="Lennon")

(om det fanns en relaterad `Author`-modell), om det inte fanns någon `author` associerad med en post, skulle det behandlas som om det inte heller fanns något `name` bifogat, snarare än att ge ett fel på grund av den saknade `author`. Vanligtvis är detta precis vad du vill ska hända. Det enda fallet där det kan vara förvirrande är om du använder `isnull`. Alltså:

    Blog.objects.filter(entry__authors__name__isnull=True)

kommer att returnera `Blog`-objekt som har ett tomt `namn` på `författaren` och även de som har en tom `författare` på `inlägget`. Om du inte vill ha de senare objekten kan du skriva:

    Blog.objects.filter(entry__authors__isnull=False, entry__authors__name__isnull=True)

#### Spänner över flervärdiga relationer

När man spänner över en `ManyToManyField` eller en omvänd `ForeignKey` (t.ex. från `Blog` till `Entry`), väcker filtrering på flera attribut frågan om man ska kräva att varje attribut sammanfaller i samma relaterade objekt. Vi kan söka efter bloggar som har ett inlägg från 2008 med ”Lennon” i rubriken, eller så kan vi söka efter bloggar som bara har något inlägg från 2008 samt något nyare eller äldre inlägg med ”Lennon” i rubriken.

För att välja ut alla bloggar som innehåller minst ett inlägg från 2008 som har ”Lennon” i rubriken (samma inlägg uppfyller båda villkoren), skulle vi skriva:

    Blog.objects.filter(entry__headline__contains="Lennon", entry__pub_date__year=2008)

Annars, för att utföra en mer tillåtande fråga som väljer alla bloggar med bara något inlägg med ”Lennon” i rubriken och något inlägg från 2008, skulle vi skriva:

    Blog.objects.filter(entry__headline__contains="Lennon").filter(
        entry__pub_date__year=2008
    )

Anta att det bara finns en blogg som har både poster som innehåller ”Lennon” och poster från 2008, men att ingen av posterna från 2008 innehöll ”Lennon”. Den första frågan skulle inte returnera några bloggar, men den andra frågan skulle returnera den enda bloggen. (Detta beror på att de poster som väljs av det andra filtret kanske eller kanske inte är desamma som posterna i det första filtret. Vi filtrerar `Blog`-objekten med varje filteruttalande, inte `Entry`-objekten.) Kort sagt, om varje villkor behöver matcha samma relaterade objekt, bör varje innehålla ett enda `filter()`-anrop.

Observera

Eftersom den andra (mer tillåtande) frågan kedjar flera filter utförs flera kopplingar till den primära modellen, vilket kan ge upphov till dubbletter.

    >>> from datetime import date
    >>> beatles = Blog.objects.create(name="Beatles Blog")
    >>> pop = Blog.objects.create(name="Pop Music Blog")
    >>> Entry.objects.create(
    ...     blog=beatles,
    ...     headline="New Lennon Biography",
    ...     pub_date=date(2008, 6, 1),
    ... )
    <Entry: New Lennon Biography>
    >>> Entry.objects.create(
    ...     blog=beatles,
    ...     headline="New Lennon Biography in Paperback",
    ...     pub_date=date(2009, 6, 1),
    ... )
    <Entry: New Lennon Biography in Paperback>
    >>> Entry.objects.create(
    ...     blog=pop,
    ...     headline="Best Albums of 2008",
    ...     pub_date=date(2008, 12, 15),
    ... )
    <Entry: Best Albums of 2008>
    >>> Entry.objects.create(
    ...     blog=pop,
    ...     headline="Lennon Would Have Loved Hip Hop",
    ...     pub_date=date(2020, 4, 1),
    ... )
    <Entry: Lennon Would Have Loved Hip Hop>
    >>> Blog.objects.filter(
    ...     entry__headline__contains="Lennon",
    ...     entry__pub_date__year=2008,
    ... )
    <QuerySet [<Blog: Beatles Blog>]>
    >>> Blog.objects.filter(
    ...     entry__headline__contains="Lennon",
    ... ).filter(
    ...     entry__pub_date__year=2008,
    ... )
    <QuerySet [<Blog: Beatles Blog>, <Blog: Beatles Blog>, <Blog: Pop Music Blog]>

Observera

Beteendet hos `filter()` för frågor som spänner över flervärdesrelationer, som beskrivs ovan, implementeras inte på motsvarande sätt för `exclude()`. Istället kommer villkoren i ett enda `exclude()`-anrop inte nödvändigtvis att hänvisa till samma objekt.

Till exempel skulle följande fråga utesluta bloggar som innehåller både poster med ”Lennon” i rubriken och poster som publicerades 2008:

    Blog.objects.exclude(
        entry__headline__contains="Lennon",
        entry__pub_date__year=2008,
    )

Till skillnad från beteendet när du använder `filter()` kommer detta dock inte att begränsa bloggar baserat på poster som uppfyller båda villkoren. För att göra det, dvs. för att välja alla bloggar som inte innehåller poster som publicerats med ”Lennon” och som publicerades 2008, måste du göra två frågor:

    Blog.objects.exclude(
        entry__in=Entry.objects.filter(
            headline__contains="Lennon",
            pub_date__year=2008,
        ),
    )

### Filter kan referera till fält i modellen

I de exempel som vi har gett hittills har vi konstruerat filter som jämför värdet på ett modellfält med en konstant. Men hur gör man om man vill jämföra värdet på ett modellfält med ett annat fält i samma modell?

Django tillhandahåller `F expressions` för att tillåta sådana jämförelser. Instanser av `F()` fungerar som en referens till ett modellfält i en fråga. Dessa referenser kan sedan användas i frågefilter för att jämföra värdena för två olika fält på samma modellinstans.

Om du till exempel vill hitta en lista över alla bloggposter som har fått fler kommentarer än pingbacks, konstruerar vi ett `F()`-objekt för att referera till pingback-antalet och använder det `F()`-objektet i frågan:

    >>> from django.db.models import F
    >>> Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks"))

Django stöder användningen av addition, subtraktion, multiplikation, division, modulo och potensaritmetik med `F()`-objekt, både med konstanter och med andra `F()`-objekt. För att hitta alla bloggposter med mer än två gånger så många kommentarer som pingbacks ändrar vi frågan:

    >>> Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks") * 2)

För att hitta alla poster där betyget för posten är mindre än summan av antalet pingbackar och antalet kommentarer, skulle vi ställa frågan:

    >>> Entry.objects.filter(rating__lt=F("number_of_comments") + F("number_of_pingbacks"))

Du kan också använda dubbla understrykningar för att spänna över relationer i ett `F()`-objekt. Ett `F()`-objekt med en dubbel understrykning introducerar alla kopplingar som behövs för att komma åt det relaterade objektet. Om du t.ex. vill hämta alla poster där författarens namn är detsamma som bloggens namn kan du ställa följande fråga:

    >>> Entry.objects.filter(authors__name=F("blog__name"))

För datum- och datum/tid-fält kan du lägga till eller dra ifrån ett `timedelta`-objekt. Följande skulle returnera alla poster som ändrades mer än 3 dagar efter att de publicerades:

    >>> from datetime import timedelta
    >>> Entry.objects.filter(mod_date__gt=F("pub_date") + timedelta(days=3))

Objekten `F()` stöder bitvisa operationer med `.bitand()`, `.bitor()`, `.bitxor()`, `.bitrightshift()` och `.bitleftshift()`. Till exempel:

    >>> F("somefield").bitand(16)

Oracle

Oracle stöder inte bitvis XOR-operation.

### Uttryck kan referera till transformationer

Django stöder användning av transformationer i uttryck.

Till exempel för att hitta alla `Entry`-objekt som publicerades samma år som de senast ändrades:

    >>> from django.db.models import F
    >>> Entry.objects.filter(pub_date__year=F("mod_date__year"))

För att hitta det tidigaste året som en post publicerades kan vi ställa frågan:

    >>> from django.db.models import Min
    >>> Entry.objects.aggregate(first_published_year=Min("pub_date__year"))

Detta exempel visar värdet på den högst rankade posten och det totala antalet kommentarer på alla poster för varje år:

    >>> from django.db.models import OuterRef, Subquery, Sum
    >>> Entry.objects.values("pub_date__year").annotate(
    ...     top_rating=Subquery(
    ...         Entry.objects.filter(
    ...             pub_date__year=OuterRef("pub_date__year"),
    ...         )
    ...         .order_by("-rating")
    ...         .values("rating")[:1]
    ...     ),
    ...     total_comments=Sum("number_of_comments"),
    ... )

### Genvägen `pk` för uppslagning

För enkelhetens skull tillhandahåller Django en genväg för uppslagning `pk`, som står för ”primary key”.

I exemplet med modellen `Blog` är primärnyckeln fältet `id`, så dessa tre påståenden är likvärdiga:

    >>> Blog.objects.get(id__exact=14)  # Explicit form
    >>> Blog.objects.get(id=14)  # __exact is implied
    >>> Blog.objects.get(pk=14)  # pk implies id__exact

Användningen av `pk` är inte begränsad till `__exact`-frågor - alla frågetermer kan kombineras med `pk` för att utföra en fråga på primärnyckeln i en modell:

    # Get blogs entries with id 1, 4 and 7
    >>> Blog.objects.filter(pk__in=[1, 4, 7])

    # Get all blog entries with id > 14
    >>> Blog.objects.filter(pk__gt=14)

`pk`-uppslag fungerar också över sammanfogningar. Till exempel är dessa tre uttalanden likvärdiga:

    >>> Entry.objects.filter(blog__id__exact=3)  # Explicit form
    >>> Entry.objects.filter(blog__id=3)  # __exact is implied
    >>> Entry.objects.filter(blog__pk=3)  # __pk implies __id__exact

### Utelämnande av procenttecken och understrykningstecken i `LIKE`-satser

De fältuppslagningar som motsvarar `LIKE` SQL-satser (`iexact`, `contains`, `icontains`, `startswith`, `istartswith`, `endswith` och `iendswith`) kommer automatiskt att undkomma de två specialtecken som används i `LIKE`-satser - procenttecknet och understrecket. (I en `LIKE`-sats betyder procenttecknet ett jokertecken med flera tecken och understreckaren ett jokertecken med ett tecken)

Detta innebär att saker och ting ska fungera intuitivt, så att abstraktionen inte läcker. Om du t.ex. vill hämta alla poster som innehåller ett procenttecken använder du procenttecknet som vilket annat tecken som helst:

    >>> Entry.objects.filter(headline__contains="%")

Django tar hand om citering åt dig; den resulterande SQL kommer att se ut ungefär så här:

    SELECT ... WHERE headline LIKE '%\%%';

Detsamma gäller för understrykningstecken. Både procenttecken och understrykningar hanteras transparent åt dig.

### Cachelagring och ”QuerySet

Varje `QuerySet` innehåller en cache för att minimera databasåtkomst. Att förstå hur det fungerar gör att du kan skriva den mest effektiva koden.

I en nyskapad `QuerySet` är cacheminnet tomt. Första gången en `QuerySet` utvärderas - och därmed en databasfråga sker - sparar Django frågeresultaten i `QuerySet` itereras över). Efterföljande utvärderingar av `QuerySet` återanvänder de cachade resultaten.

Tänk på detta cachningsbeteende, eftersom det kan drabba dig om du inte använder dina `QuerySet` på rätt sätt. Till exempel kommer följande att skapa två `QuerySet`s, utvärdera dem och kasta bort dem:

    >>> print([e.headline for e in Entry.objects.all()])
    >>> print([e.pub_date for e in Entry.objects.all()])

Det innebär att samma databasförfrågan kommer att köras två gånger, vilket effektivt fördubblar din databasbelastning. Det finns också en möjlighet att de två listorna kanske inte innehåller samma databasposter, eftersom en `Entry` kan ha lagts till eller tagits bort i den delade sekunden mellan de två förfrågningarna.

För att undvika detta problem, spara `QuerySet` och återanvänd den:

    >>> queryset = Entry.objects.all()
    >>> print([p.headline for p in queryset])  # Evaluate the query set.
    >>> print([p.pub_date for p in queryset])  # Reuse the cache from the evaluation.

#### När `QuerySet` inte cachelagras

Querysets do not always cache their results. When evaluating only part of the queryset, the cache is checked, but if it is not populated then the items returned by the subsequent query are not cached. Specifically, this means that limiting the queryset using an array slice or an index will not populate the cache.

Om man t.ex. upprepade gånger hämtar ett visst index i ett queryset-objekt kommer databasen att genomsökas varje gång:

    >>> queryset = Entry.objects.all()
    >>> print(queryset[5])  # Queries the database
    >>> print(queryset[5])  # Queries the database again

Om hela frågeuppsättningen redan har utvärderats kommer dock cacheminnet att kontrolleras i stället:

    >>> queryset = Entry.objects.all()
    >>> [entry for entry in queryset]  # Queries the database
    >>> print(queryset[5])  # Uses cache
    >>> print(queryset[5])  # Uses cache

Här följer några exempel på andra åtgärder som leder till att hela frågeuppsättningen utvärderas och därmed fyller på cacheminnet:

    >>> [entry for entry in queryset]
    >>> bool(queryset)
    >>> entry in queryset
    >>> list(queryset)

Observera

Att bara skriva ut querysetet kommer inte att fylla på cachen. Detta beror på att anropet till `__repr__()` endast returnerar en del av hela frågeuppsättningen.

## Asynkrona förfrågningar

Om du skriver asynkrona vyer eller kod kan du inte använda ORM för frågor på det sätt som vi har beskrivit ovan, eftersom du inte kan anropa blockerande synkron kod från asynkron kod - det kommer att blockera händelseslingan (eller, mer troligt, Django kommer att märka och höja en `SynchronousOnlyOperation` för att förhindra att det händer).

Lyckligtvis kan du göra många frågor med hjälp av Djangos asynkrona fråge-API. Varje metod som kan blockera - till exempel `get()` eller `delete()` - har en asynkron variant (`aget()` eller `adelete()`), och när du itererar över resultat kan du använda asynkron iteration (`async for`) istället.

### Fråga iteration

Standardmetoden för att iterera över en fråga - med `for` - kommer att resultera i en blockerande databasfråga bakom kulisserna eftersom Django laddar resultaten vid iterationstiden. För att åtgärda detta kan du byta till `async for`:

    async for entry in Authors.objects.filter(name__startswith="A"):
        ...

Tänk på att du inte heller kan göra andra saker som kan iterera över queryset, till exempel att linda `list()` runt den för att tvinga fram dess utvärdering (du kan använda `async for` i en comprehension, om du vill det).

Eftersom `QuerySet`-metoder som `filter()` och `exclude()` faktiskt inte kör frågan - de ställer in queryset för att köras när det itereras över - kan du använda dem fritt i asynkron kod. För en guide till vilka metoder som kan fortsätta att användas på det här sättet och vilka som har asynkrona versioner, läs nästa avsnitt.

### `QuerySet` och manager-metoder

Vissa metoder för hanterare och frågeuppsättningar - som `get()` och `first()` - tvingar fram exekvering av frågeuppsättningen och är blockerande. Vissa, som `filter()` och `exclude()`, tvingar inte fram exekvering och är därför säkra att köra från asynkron kod. Men hur ska du kunna se skillnaden?

Även om du kan rota runt och se om det finns en `a`-prefixerad version av metoden (till exempel har vi `aget()` men inte `afilter()`), finns det ett mer logiskt sätt - leta upp vilken typ av metod det är i QuerySet-referensen.

Där hittar du metoderna för QuerySets grupperade i två avsnitt:

- Metoder som returnerar nya querysets: Dessa är de icke-blockerande och har inga asynkrona versioner. Du är fri att använda dessa i alla situationer, men läs noterna om `defer()` och `only()` innan du använder dem.

- Metoder som inte returnerar querysets: Dessa är de blockerande och har asynkrona versioner - det asynkrona namnet för varje metod anges i dokumentationen, men vårt standardmönster är att lägga till prefixet `a`.

Med hjälp av denna distinktion kan du räkna ut när du behöver använda asynkrona versioner och när du inte behöver göra det. Här är till exempel en giltig asynkron fråga:

    user = await User.objects.filter(username=my_input).afirst()

`filter()` returnerar en queryset, och därför går det bra att fortsätta kedja den i en asynkron miljö, medan `first()` utvärderar och returnerar en modellinstans - därför ändrar vi till `afirst()` och använder `await` i början av hela uttrycket för att anropa det på ett asynkronvänligt sätt.

Observera

Om du glömmer att lägga in `await`-delen kan du se fel som ”coroutine-objektet har inget attribut x” eller ”<coroutine …>” strängar i stället för dina modellinstanser. Om du någonsin ser dessa, saknar du en `await` någonstans för att göra den coroutine till ett verkligt värde.

### Transaktioner

Transaktioner stöds inte för närvarande med asynkrona frågor och uppdateringar. Du kommer att upptäcka att försök att använda en sådan ger upphov till `SynchronousOnlyOperation`.

Om du vill använda en transaktion föreslår vi att du skriver din ORM-kod i en separat, synkron funktion och sedan anropar den med hjälp av `sync_to_async` - se Asynkront stöd för mer information.

## Fråga om `JSONField`

Lookups implementation är annorlunda i `JSONField`, främst på grund av förekomsten av nyckeltransformationer. För att demonstrera kommer vi att använda följande exempelmodell:

    from django.db import models

    class Dog(models.Model):
        name = models.CharField(max_length=200)
        data = models.JSONField(null=True)

        def __str__(self):
            return self.name

### Lagring av och frågor om `None`

Som med andra fält kommer lagring av `None` som fältets värde att lagra det som SQL `NULL`. Även om det inte rekommenderas är det möjligt att lagra JSON skalär `null` istället för SQL `NULL` genom att använda `Value(None, JSONField())`.

Oavsett vilket av värdena som lagras, när det hämtas från databasen, är Python-representationen av JSON-skalaren `null` densamma som SQL `NULL`, dvs `None`. Därför kan det vara svårt att skilja mellan dem.

This only applies to `None` as the top-level value of the field. If `None` is inside a `list` or `dict`, it will always be interpreted as JSON `null`.

Vid frågor kommer värdet `None` alltid att tolkas som JSON `null`. För att fråga efter SQL `NULL`, använd `isnull``:

    >>> Dog.objects.create(name="Max", data=None)  # SQL NULL.
    <Dog: Max>
    >>> Dog.objects.create(name="Archie", data=Value(None, JSONField()))  # JSON null.
    <Dog: Archie>
    >>> Dog.objects.filter(data=None)
    <QuerySet [<Dog: Archie>]>
    >>> Dog.objects.filter(data=Value(None, JSONField()))
    <QuerySet [<Dog: Archie>]>
    >>> Dog.objects.filter(data__isnull=True)
    <QuerySet [<Dog: Max>]>
    >>> Dog.objects.filter(data__isnull=False)
    <QuerySet [<Dog: Archie>]>

Om du inte är säker på att du vill arbeta med SQL-värden av typen `NULL`, bör du överväga att ange `null=False` och tillhandahålla en lämplig standard för tomma värden, t.ex. `default=dict`.

Observera

Lagring av JSON-skalaren `null` bryter inte mot `null=False`.

### Nyckel-, index- och banomvandlingar

Om du vill göra en sökning baserad på en viss nyckel i en ordbok använder du den nyckeln som uppslagsnamn:

    >>> Dog.objects.create(
    ...     name="Rufus",
    ...     data={
    ...         "breed": "labrador",
    ...         "owner": {
    ...             "name": "Bob",
    ...             "other_pets": [
    ...                 {
    ...                     "name": "Fishy",
    ...                 }
    ...             ],
    ...         },
    ...     },
    ... )
    <Dog: Rufus>
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": None})
    <Dog: Meg>
    >>> Dog.objects.filter(data__breed="collie")
    <QuerySet [<Dog: Meg>]>

Flera nycklar kan kedjas ihop för att bilda en sökvägsuppslagning:

    >>> Dog.objects.filter(data__owner__name="Bob")
    <QuerySet [<Dog: Rufus>]>

Om nyckeln är ett heltal tolkas den som en indextransform i en array:

    >>> Dog.objects.filter(data__owner__other_pets__0__name="Fishy")
    <QuerySet [<Dog: Rufus>]>

If the key is a negative integer, it cannot be used in a filter keyword directly, but you can still use dictionary unpacking to use it in a query:

    >>> Dog.objects.filter(**{"data__owner__other_pets__-1__name": "Fishy"})
    <QuerySet [<Dog: Rufus>]>

MySQL, MariaDB, and Oracle

Negative JSON array indices are not supported.

Changed in Django 6.0:

SQLite support for negative JSON array indices was added.

Om den nyckel som du vill söka på krockar med namnet på en annan lookup, använd istället lookupen `contains`.

För att söka efter nycklar som saknas, använd `isnull` lookup:

    >>> Dog.objects.create(name="Shep", data={"breed": "collie"})
    <Dog: Shep>
    >>> Dog.objects.filter(data__owner__isnull=True)
    <QuerySet [<Dog: Shep>]>

Observera

Uppslagningsexemplen ovan använder implicit uppslagningen `exact`. Nyckel-, index- och sökvägstransformationer kan också kedjas med: `icontains`, `endswith`, `iendswith`, `iexact`, `regex`, `iregex`, `startswith`, `istartswith`, `lt`, `lte`, `gt`, and `gte`, as well as with Inneslutning och nyckeluppslagningar.

#### `KT()` uttryck

class KT(lookup)

  Representerar textvärdet för en nyckel-, index- eller sökvägstransformation av `JSONField`. Du kan använda den dubbla understrecksnoteringen i `lookup` för att kedja nyckel- och indextransformationer för ordböcker.

  Till exempel:

      >>> from django.db.models.fields.json import KT
      >>> Dog.objects.create(
      ...     name="Shep",
      ...     data={
      ...         "owner": {"name": "Bob"},
      ...         "breed": ["collie", "lhasa apso"],
      ...     },
      ... )
      <Dog: Shep>
      >>> Dog.objects.annotate(
      ...     first_breed=KT("data__breed__1"), owner_name=KT("data__owner__name")
      ... ).filter(first_breed__startswith="lhasa", owner_name="Bob")
      <QuerySet [<Dog: Shep>]>

Observera

På grund av det sätt på vilket sökvägsfrågor fungerar är `exclude()` och `filter()` inte garanterade att producera uttömmande uppsättningar. Om du vill inkludera objekt som inte har sökvägen, lägg till `isnull` lookup.

Varning

Eftersom vilken sträng som helst kan vara en nyckel i ett JSON-objekt kommer alla andra uppslagningar än de som anges nedan att tolkas som en nyckeluppslagning. Inga felmeddelanden skickas ut. Var extra försiktig med skrivfel och kontrollera alltid att dina frågor fungerar som du tänkt dig.

MariaDB- och Oracle-användare

Om du använder `order_by()` på nyckel-, index- eller sökvägstransformationer sorteras objekten med hjälp av strängrepresentationen av värdena. Detta beror på att MariaDB och Oracle Database inte tillhandahåller en funktion som konverterar JSON-värden till deras motsvarande SQL-värden.

Oracle-användare

Om du använder `None` som uppslagsvärde i en `exclude()`-fråga i Oracle Database returneras objekt som inte har `null` som värde på den angivna sökvägen, inklusive objekt som inte har sökvägen. På andra databasbackends kommer frågan att returnera objekt som har sökvägen och värdet är inte `null`.

PostgreSQL-användare

På PostgreSQL, om endast en nyckel eller ett index används, används SQL-operatören `->`. Om flera operatörer används används operatören `` #>``.

SQLite-användare

I SQLite kommer strängvärdena `"true"`, `"false"` och `"null"` alltid att tolkas som `True`, `False` respektive JSON `null`.

### Inneslutning och nyckeluppslagningar

#### `innehåller`

Uppslaget `contains` åsidosätts för `JSONField`. De objekt som returneras är de där den givna `dict` av nyckel-värdepar alla finns i fältets toppnivå. Till exempel:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador", "owner": "Bob"})
    <Dog: Rufus>
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
    <Dog: Meg>
    >>> Dog.objects.create(name="Fred", data={})
    <Dog: Fred>
    >>> Dog.objects.create(
    ...     name="Merry", data={"breed": "pekingese", "tricks": ["fetch", "dance"]}
    ... )
    >>> Dog.objects.filter(data__contains={"owner": "Bob"})
    <QuerySet [<Dog: Rufus>, <Dog: Meg>]>
    >>> Dog.objects.filter(data__contains={"breed": "collie"})
    <QuerySet [<Dog: Meg>]>
    >>> Dog.objects.filter(data__contains={"tricks": ["dance"]})
    <QuerySet [<Dog: Merry>]>

Oracle och SQLite

`contains` stöds inte av Oracle och SQLite.

#### `innehålls_av`

Detta är motsatsen till `contains` - de objekt som returneras är de där nyckel-värdeparen i objektet är en delmängd av dem i det värde som skickas. Till exempel:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador", "owner": "Bob"})
    <Dog: Rufus>
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
    <Dog: Meg>
    >>> Dog.objects.create(name="Fred", data={})
    <Dog: Fred>
    >>> Dog.objects.create(
    ...     name="Merry", data={"breed": "pekingese", "tricks": ["fetch", "dance"]}
    ... )
    >>> Dog.objects.filter(data__contained_by={"breed": "collie", "owner": "Bob"})
    <QuerySet [<Dog: Meg>, <Dog: Fred>]>
    >>> Dog.objects.filter(data__contained_by={"breed": "collie"})
    <QuerySet [<Dog: Fred>]>
    >>> Dog.objects.filter(
    ...     data__contained_by={"breed": "pekingese", "tricks": ["dance", "fetch", "hug"]}
    ... )
    <QuerySet [<Dog: Merry>, <Dog: Fred>]>

Oracle och SQLite

`contained_by` stöds inte av Oracle och SQLite.

#### `har_nyckel`

Returnerar objekt där den angivna nyckeln finns i den översta nivån av data. Till exempel:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    <Dog: Rufus>
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
    <Dog: Meg>
    >>> Dog.objects.filter(data__has_key="owner")
    <QuerySet [<Dog: Meg>]>

#### `har_nycklar`

Returnerar objekt där alla de angivna nycklarna finns på den översta nivån i data. Till exempel:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    <Dog: Rufus>
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
    <Dog: Meg>
    >>> Dog.objects.filter(data__has_keys=["breed", "owner"])
    <QuerySet [<Dog: Meg>]>

#### `har_några_nycklar`

Returnerar objekt där någon av de angivna nycklarna finns på den översta nivån i data. Till exempel:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    <Dog: Rufus>
    >>> Dog.objects.create(name="Meg", data={"owner": "Bob"})
    <Dog: Meg>
    >>> Dog.objects.filter(data__has_any_keys=["owner", "breed"])
    <QuerySet [<Dog: Rufus>, <Dog: Meg>]>

## Komplexa uppslagningar med `Q`-objekt

Frågor med nyckelordsargument – i `filter()`, etc. – är ”AND” tillsammans. Om du behöver köra mer komplexa frågor (till exempel frågor med `OR`-satser) kan du använda `Q objects`.

Ett `Q-objekt` (`django.db.models.Q`) är ett objekt som används för att kapsla in en samling nyckelordsargument. Dessa nyckelordsargument specificeras som i ”Fältuppslagningar” ovan.

Till exempel kapslar detta `Q`-objekt in en enda `LIKE`-fråga:

    from django.db.models import Q

    Q(question__startswith="What")

`Q`-objekt kan kombineras med hjälp av operatörerna `&`, `|` och `^`. När en operator används på två `Q`-objekt, ger det ett nytt `Q`-objekt.

Till exempel ger detta uttalande ett enda `Q`-objekt som representerar ”OR” av två `"question__startswith"`-frågor:

    Q(question__startswith="Who") | Q(question__startswith="What")

Detta motsvarar följande SQL `WHERE` klausul:

    WHERE question LIKE 'Who%' OR question LIKE 'What%'

Du kan komponera satser av godtycklig komplexitet genom att kombinera `Q`-objekt med operatörerna `&`, `|` och `^` och använda parentetisk gruppering. Dessutom kan `Q`-objekt negeras med operatorn `~`, vilket möjliggör kombinerade uppslagningar som kombinerar både en normal fråga och en negerad (`NOT`) fråga:

    Q(question__startswith="Who") | ~Q(pub_date__year=2005)

Varje uppslagsfunktion som tar nyckelordsargument (t.ex. `filter()`, `exclude()`, `get()`) kan också skickas ett eller flera `Q`-objekt som positionella (ej namngivna) argument. Om du ger flera `Q`-objektargument till en uppslagsfunktion kommer argumenten att ”AND”-kopplas ihop. Till exempel:

    Poll.objects.get(
        Q(question__startswith="Who"),
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    )

…översätts ungefär till SQL:

    SELECT * from polls WHERE question LIKE 'Who%'
        AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

Uppslagsfunktioner kan blanda användningen av `Q`-objekt och nyckelordsargument. Alla argument som anges i en lookup-funktion (oavsett om det är nyckelordsargument eller `Q`-objekt) ”AND”-kopplas ihop. Om ett `Q`-objekt anges måste det dock föregå definitionen av eventuella nyckelordsargument. Till exempel:

    Poll.objects.get(
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
        question__startswith="Who",
    )

… skulle vara en giltig fråga, motsvarande det föregående exemplet; men:

    # INVALID QUERY
    Poll.objects.get(
        question__startswith="Who",
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    )

… skulle inte vara giltigt.

Se även

OR lookups examples i Djangos enhetstester visar några möjliga användningsområden för `Q`.

## Jämförelse av objekt

För att jämföra två modellinstanser använder du Pythons standardjämförelseoperator, det dubbla likhetstecknet: `==`. Bakom kulisserna jämför det de primära nyckelvärdena för två modeller.

Med hjälp av exemplet `Entry` ovan är följande två uttalanden likvärdiga:

    >>> some_entry == other_entry
    >>> some_entry.id == other_entry.id

Om en modells primärnyckel inte heter `id` är det inget problem. Jämförelser kommer alltid att använda primärnyckeln, oavsett vad den heter. Om till exempel en modells primärnyckelfält heter `name` är dessa två påståenden likvärdiga:

    >>> some_obj == other_obj
    >>> some_obj.name == other_obj.name

## Radering av objekt

Metoden delete heter lägligt nog `delete()`. Denna metod raderar omedelbart objektet och returnerar antalet objekt som raderats och en ordbok med antalet raderingar per objekttyp. Exempel på detta:

    >>> e.delete()
    (1, {'blog.Entry': 1})

Du kan också radera objekt i bulk. Varje `QuerySet` har en `delete()`-metod, som raderar alla medlemmar i den `QuerySet`.

Detta raderar till exempel alla `Entry`-objekt med `pub_date` år 2005:

    >>> Entry.objects.filter(pub_date__year=2005).delete()
    (5, {'webapp.Entry': 5})

Tänk på att detta, när det är möjligt, kommer att utföras enbart i SQL, och därför kommer inte `delete()`-metoderna för enskilda objektinstanser nödvändigtvis att anropas under processen. Om du har tillhandahållit en anpassad `delete()`-metod för en modellklass och vill se till att den anropas, måste du ”manuellt” radera instanser av den modellen (t.ex, genom att iterera över en `QuerySet` och anropa `delete()` på varje objekt individuellt) i stället för att använda bulk `delete()`-metoden för en `QuerySet`.

När Django raderar ett objekt emulerar det som standard beteendet hos SQL-begränsningen `ON DELETE CASCADE` - med andra ord kommer alla objekt som hade främmande nycklar som pekar på det objekt som ska raderas att raderas tillsammans med det. Till exempel:

    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()

Detta kaskadbeteende kan anpassas via argumentet `on_delete` till `ForeignKey`.

Observera att `delete()` är den enda `QuerySet`-metoden som inte exponeras på en `Manager` själv. Detta är en säkerhetsmekanism för att förhindra att du av misstag begär `Entry.objects.delete()` och raderar alla posterna. Om du vill ta bort alla objekt måste du uttryckligen begära en komplett frågeuppsättning:

    Entry.objects.all().delete()

## Kopiera modellinstanser

Även om det inte finns någon inbyggd metod för att kopiera modellinstanser, är det möjligt att enkelt skapa en ny instans med alla fältvärden kopierade. I det enklaste fallet kan du ställa in `pk` till `None` och `_state.adding` till `True`. Med hjälp av vårt bloggexempel:

    blog = Blog(name="My blog", tagline="Blogging is easy")
    blog.save()  # blog.pk == 1

    blog.pk = None
    blog._state.adding = True
    blog.save()  # blog.pk == 2

Saker och ting blir mer komplicerade om man använder sig av arv. Tänk dig en subklass av `Blog`:

    class ThemeBlog(Blog):
        theme = models.CharField(max_length=200)

    django_blog = ThemeBlog(name="Django", tagline="Django is easy", theme="python")
    django_blog.save()  # django_blog.pk == 3

På grund av hur arv fungerar måste du ställa in både `pk` och `id` till `None`, och `_state.adding` till `True`:

    django_blog.pk = None
    django_blog.id = None
    django_blog._state.adding = True
    django_blog.save()  # django_blog.pk == 4

Denna process kopierar inte relationer som inte är en del av modellens databastabell. Till exempel har `Entry` en `ManyToManyField` till `Author`. När du har duplicerat en post måste du ställa in relationerna många-till-många för den nya posten:

    entry = Entry.objects.all()[0]  # some previous entry
    old_authors = entry.authors.all()
    entry.pk = None
    entry._state.adding = True
    entry.save()
    entry.authors.set(old_authors)

För ett `OneToOneField` måste du duplicera det relaterade objektet och tilldela det till det nya objektets fält för att undvika att bryta mot den unika begränsningen för en-till-en. Om vi till exempel antar att `entry` redan är duplicerat enligt ovan:

    detail = EntryDetail.objects.all()[0]
    detail.pk = None
    detail._state.adding = True
    detail.entry = entry
    detail.save()

Note that it is not possible to copy instances of models with deferred fields using this pattern unless values are assigned to them:

    >>> blog = Blog.objects.defer("name")[0]
    >>> blog.pk = None
    >>> blog._state.adding = True
    >>> blog.save()
    Traceback (most recent call last):
        ...
    AttributeError: Cannot retrieve deferred field 'name' from an unsaved model.
    >>> blog.name = "Another Blog"
    >>> blog.save()

## Uppdatering av flera objekt samtidigt

Ibland vill man sätta ett fält till ett visst värde för alla objekt i en `QuerySet`. Det kan du göra med metoden `update()`. Till exempel:

    # Update all the headlines with pub_date in 2007.
    Entry.objects.filter(pub_date__year=2007).update(headline="Everything is the same")

Du kan bara ställa in fält som inte är relationsfält och `ForeignKey`-fält med den här metoden. För att uppdatera ett fält som inte är ett relationsfält anger du det nya värdet som en konstant. För att uppdatera `ForeignKey`-fält anger du det nya värdet som den nya modellinstans du vill peka på. Till exempel:

    >>> b = Blog.objects.get(pk=1)

    # Change every Entry so that it belongs to this Blog.
    >>> Entry.objects.update(blog=b)

Metoden `update()` tillämpas omedelbart och returnerar antalet rader som matchas av frågan (vilket kanske inte är lika med antalet rader som uppdaterats om vissa rader redan har det nya värdet). Den enda begränsningen för `QuerySet` som uppdateras är att den endast kan komma åt en databastabell: modellens huvudtabell. Du kan filtrera baserat på relaterade fält, men du kan bara uppdatera kolumner i modellens huvudtabell. Ett exempel:

    >>> b = Blog.objects.get(pk=1)

    # Update all the headlines belonging to this Blog.
    >>> Entry.objects.filter(blog=b).update(headline="Everything is the same")

Tänk på att metoden `update()` konverteras direkt till en SQL-sats. Det är en bulkoperation för direkta uppdateringar. Den kör inte några `save()`-metoder på dina modeller, eller avger signalerna `pre_save` eller `post_save` (som är en konsekvens av att anropa `save()`), eller hedrar fältalternativet `auto_now`. Om du vill spara varje objekt i en `QuerySet` och se till att metoden `save()` anropas på varje instans, behöver du ingen speciell funktion för att hantera det. Loopa över dem och anropa `save()`:

    for item in my_queryset:
        item.save()

Anrop till update kan också använda `F expressions` för att uppdatera ett fält baserat på värdet av ett annat fält i modellen. Detta är särskilt användbart för att öka räknare baserat på deras aktuella värde. Till exempel för att öka antalet pingbackar för varje inlägg i bloggen:

    >>> Entry.objects.update(number_of_pingbacks=F("number_of_pingbacks") + 1)

Men till skillnad från `F()`-objekt i filter- och exkluderingsklausuler kan du inte införa joins när du använder `F()`-objekt i en uppdatering - du kan bara referera till fält som är lokala för den modell som uppdateras. Om du försöker införa en join med ett `F()`-objekt, kommer ett `FieldError` att uppstå:

    # This will raise a FieldError
    >>> Entry.objects.update(headline=F("blog__name"))

## Relaterade objekt

När du definierar en relation i en modell (dvs. en `ForeignKey`, `OneToOneField` eller `ManyToManyField`) kommer instanser av den modellen att ha ett bekvämt API för att komma åt det eller de relaterade objekten.

Med hjälp av modellerna högst upp på denna sida kan till exempel ett `Entry`-objekt `e` få sitt associerade `Blog`-objekt genom att komma åt `blog`-attributet: `e.blog`.

(Bakom kulisserna implementeras denna funktionalitet av Python descriptors. Detta borde egentligen inte spela någon roll för dig, men vi påpekar det här för den nyfikne)

Django skapar också API-åtkomst för den ”andra” sidan av relationen - länken från den relaterade modellen till den modell som definierar relationen. Till exempel har ett `Blog`-objekt `b` tillgång till en lista över alla relaterade `Entry`-objekt via `entry_set`-attributet: `b.entry_set.all()`.

Alla exempel i detta avsnitt använder modellerna `Blog`, `Author` och `Entry` som definieras högst upp på denna sida.

### En-till-många-relationer

#### Framåt

Om en modell har en `ForeignKey`, kommer instanser av den modellen att ha tillgång till det relaterade (främmande) objektet via ett attribut för modellen.

Exempel:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog  # Returns the related Blog object.

Du kan hämta och ställa in via ett foreign-key-attribut. Som du kanske förväntar dig sparas inte ändringar av den främmande nyckeln i databasen förrän du anropar `save()`. Exempel på detta:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog = some_blog
    >>> e.save()

Om ett fält i `ForeignKey` har inställningen `null=True` (dvs. det tillåter `NULL`-värden) kan du tilldela `None` för att ta bort relationen. Exempel på detta:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog = None
    >>> e.save()  # "UPDATE blog_entry SET blog_id = NULL ...;"

Framåtriktad åtkomst till en-till-många-relationer cachelagras första gången det relaterade objektet nås. Efterföljande åtkomst till främmande nyckel på samma objektinstans cachelagras. Exempel på detta:

    >>> e = Entry.objects.get(id=2)
    >>> print(e.blog)  # Hits the database to retrieve the associated Blog.
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.

Observera att metoden `select_related()` `QuerySet` rekursivt fyller på cacheminnet med alla en-till-många-relationer i förväg. Exempel på detta:

    >>> e = Entry.objects.select_related().get(id=2)
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.

#### Följa relationer ”baklänges”

Om en modell har en `ForeignKey`, kommer instanser av modellen med utländsk nyckel att ha tillgång till en `Manager` som returnerar alla instanser av den första modellen. Som standard har denna `Manager` namnet `FOO_set`, där `FOO` är källmodellens namn, med gemener. Denna `Manager` returnerar `QuerySet`-instanser, som kan filtreras och manipuleras enligt beskrivningen i avsnittet ”Hämta objekt” ovan.

Exempel:

    >>> b = Blog.objects.get(id=1)
    >>> b.entry_set.all()  # Returns all Entry objects related to Blog.

    # b.entry_set is a Manager that returns QuerySets.
    >>> b.entry_set.filter(headline__contains="Lennon")
    >>> b.entry_set.count()

Du kan åsidosätta namnet `FOO_set` genom att ange parametern `related_name`` i definitionen `ForeignKey``. Om till exempel modellen `Entry` ändrades till `blog = ForeignKey(Blog, on_delete=models.CASCADE, related_name='entries')`, skulle ovanstående exempelkod se ut så här:

    >>> b = Blog.objects.get(id=1)
    >>> b.entries.all()  # Returns all Entry objects related to Blog.

    # b.entries is a Manager that returns ``QuerySet`` instances.
    >>> b.entries.filter(headline__contains="Lennon")
    >>> b.entries.count()

#### Använda en anpassad reverse manager

Som standard är `RelatedManager` som används för omvända relationer en underklass av default manager för den modellen. Om du vill ange en annan manager för en viss fråga kan du använda följande syntax:

    from django.db import models

    class Entry(models.Model):
        # ...
        objects = models.Manager()  # Default Manager
        entries = EntryManager()  # Custom Manager

    b = Blog.objects.get(id=1)
    b.entry_set(manager="entries").all()

Om `EntryManager` utförde standardfiltrering i sin `get_queryset()`-metod, skulle den filtreringen gälla för `all()`-anropet.

Genom att ange en anpassad reverse manager kan du också anropa dess anpassade metoder:

    b.entry_set(manager="entries").is_published()

Interaktion med prefetching

När du anropar `prefetch_related()` med en omvänd relation kommer standardhanteraren att användas. Om du vill hämta relaterade objekt med hjälp av en anpassad omvänd hanterare, använd `Prefetch()`. Till exempel:

    from django.db.models import Prefetch

    prefetch_manager = Prefetch("entry_set", queryset=Entry.entries.all())
    Blog.objects.prefetch_related(prefetch_manager)

#### Ytterligare metoder för att hantera relaterade objekt

Förutom `QuerySet`-metoderna som definieras i ”Hämta objekt” ovan har `ForeignKey` `Manager` ytterligare metoder som används för att hantera uppsättningen relaterade objekt. En sammanfattning av varje metod finns nedan, och fullständiga detaljer finns i related objects reference.

`add(obj1, obj2, ...)`

  Lägger till de angivna modellobjekten i den relaterade objektuppsättningen.

`skapa(**kwargs)`

  Skapar ett nytt objekt, sparar det och lägger till det i den relaterade objektuppsättningen. Returnerar det nyskapade objektet.

`remove(obj1, obj2, ...)`

  Tar bort de angivna modellobjekten från den relaterade objektuppsättningen.

`clear()`

  Tar bort alla objekt från den relaterade objektuppsättningen.

`set(objs)`

  Byt ut uppsättningen av relaterade objekt.

För att tilldela medlemmarna i en relaterad uppsättning använder du metoden `set()` med en iterabel av objektinstanser. Till exempel, om `e1` och `e2` är `Entry` instanser:

    b = Blog.objects.get(id=1)
    b.entry_set.set([e1, e2])

Om metoden `clear()` är tillgänglig kommer alla befintliga objekt att tas bort från `entry_set` innan alla objekt i iterabeln (i det här fallet en lista) läggs till i uppsättningen. Om metoden `clear()` inte är tillgänglig kommer alla objekt i iterabeln att läggas till utan att några befintliga element tas bort.

Varje ”omvänd” operation som beskrivs i detta avsnitt har en omedelbar effekt på databasen. Varje tillägg, skapande och borttagning sparas omedelbart och automatiskt i databasen.

### Många-till-många-relationer

Båda ändarna av en many-to-many-relation får automatisk API-åtkomst till den andra änden. API:et fungerar på samma sätt som en ”bakvänd” en-till-många-relation, se ovan.

En skillnad är i attributnamngivningen: Den modell som definierar `ManyToManyField` använder attributnamnet för själva fältet, medan den ”omvända” modellen använder det gemena modellnamnet för den ursprungliga modellen, plus `'_set'` (precis som omvända en-till-många-relationer).

Ett exempel gör detta lättare att förstå:

    e = Entry.objects.get(id=3)
    e.authors.all()  # Returns all Author objects for this Entry.
    e.authors.count()
    e.authors.filter(name__contains="John")

    a = Author.objects.get(id=5)
    a.entry_set.all()  # Returns all Entry objects for this Author.

Precis som `ForeignKey` kan `ManyToManyField` ange `related_name`. I exemplet ovan, om `ManyToManyField` i `Entry` hade specificerat `related_name='entries'`, skulle varje `Author`-instans ha ett `entries`-attribut istället för `entry_set`.

En annan skillnad mot en-till-många-relationer är att metoderna `add()`, `set()` och `remove()` för många-till-många-relationer accepterar primärnyckelvärden, förutom modellinstanser. Om till exempel `e1` och `e2` är `Entry`-instanser, fungerar dessa `set()`-anrop på samma sätt:

    a = Author.objects.get(id=5)
    a.entry_set.set([e1, e2])
    a.entry_set.set([e1.pk, e2.pk])

#### Filtering on many-to-many relationships

When calling `filter()` on a many-to-many relationship, be aware that the join between `Entry` and the intermediary model to `Author` is performed only once, resulting in a restrictive, or ”sticky”, filter. Consider the following example:

    >>> from datetime import date
    >>> batucada = Blog.objects.create(name="Batucada Blog")
    >>> e = Entry.objects.create(
    ...     blog=batucada,
    ...     headline="Supporting social movements with drums",
    ...     pub_date=date(2019, 6, 14),
    ... )

    >>> gloria = Author.objects.create(name="Gloria")
    >>> anna = Author.objects.create(name="Anna")
    >>> e.authors.add(gloria, anna)

    >>> anna.entry_set.filter(authors__name="Gloria")
    <QuerySet []>

This filtered query is looking for blog entries that are co-authored by `anna` and `gloria`. You would expect it to return the entry `e`. However, the filter condition, which traverses the many-to-many relationship between `Entry` and `Author`, yields an empty `QuerySet`.

Since the join between `Entry` and the intermediary model to `Author` happens only once, no single object of the joined models - i.e., a relation between one author and one entry - can fulfill the query condition (entries that are co-authored by `anna` and `gloria`). You can circumvent this behavior by chaining two consecutive `filter()` calls, resulting in two separate joins and thus a more permissive filter:

    >>> anna.entry_set.filter().filter(authors__name="Gloria")
    <QuerySet [<Entry: Supporting social movements with drums>]>

exclude() is also sticky

Please note that for this example, `exclude()` behaves similarly to `filter()` despite being implemented differently. When traversing the many-to-many relationship, it does not exclude the entry `e` despite being co-authored by Gloria:

    >>> anna.entry_set.exclude(authors__name="Gloria")
    <QuerySet [<Entry: Supporting social movements with drums>]>

When chaining a second `exclude()` call, an empty `QuerySet` is returned, as expected:

    >>> anna.entry_set.exclude().exclude(authors__name="Gloria")
    <QuerySet []>

However, in other cases, `exclude()` behaves differently from `filter()`. See the note in the ”Spanning multi-valued relationships” section above.

### En-till-en-relationer

En-till-en-relationer är mycket lika många-till-en-relationer. Om du definierar en `OneToOneField` på din modell, kommer instanser av den modellen att ha tillgång till det relaterade objektet via ett attribut för modellen.

Till exempel:

    class EntryDetail(models.Model):
        entry = models.OneToOneField(Entry, on_delete=models.CASCADE)
        details = models.TextField()

    ed = EntryDetail.objects.get(id=2)
    ed.entry  # Returns the related Entry object.

Skillnaden kommer i ”omvända” frågor. Den relaterade modellen i en en-till-en-relation har också tillgång till ett `Manager`-objekt, men det `Manager` representerar ett enda objekt, snarare än en samling objekt:

    e = Entry.objects.get(id=2)
    e.entrydetail  # returns the related EntryDetail object

Om inget objekt har tilldelats denna relation kommer Django att göra ett undantag för `DoesNotExist`.

Instanser kan tilldelas den omvända relationen på samma sätt som du skulle tilldela den framåtriktade relationen:

    e.entrydetail = ed

### Hur är de bakåtriktade relationerna möjliga?

Andra objektrelationella mappare kräver att du definierar relationer på båda sidor. Django-utvecklarna anser att detta är ett brott mot DRY-principen (Don’t Repeat Yourself), så Django kräver bara att du definierar relationen i ena änden.

Men hur är detta möjligt, med tanke på att en modellklass inte vet vilka andra modellklasser som är relaterade till den förrän dessa andra modellklasser har laddats?

Svaret ligger i `appregistret`. När Django startar importerar den varje applikation som listas i `INSTALLED_APPS`, och sedan modulen `models` i varje applikation. När en ny modellklass skapas lägger Django till bakåtrelationer till alla relaterade modeller. Om de relaterade modellerna inte har importerats ännu, håller Django reda på relationerna och lägger till dem när de relaterade modellerna så småningom importeras.

Av den anledningen är det särskilt viktigt att alla modeller du använder definieras i applikationer som finns listade i `INSTALLED_APPS`. Annars kanske inte baklängesrelationerna fungerar som de ska.

### Frågor över relaterade objekt

Förfrågningar som involverar relaterade objekt följer samma regler som förfrågningar som involverar normala värdefält. När du anger det värde som en fråga ska matcha kan du använda antingen en objektinstans i sig eller primärnyckelvärdet för objektet.

Om du till exempel har ett bloggobjekt `b` med `id=5`, skulle följande tre frågor vara identiska:

    Entry.objects.filter(blog=b)  # Query using object instance
    Entry.objects.filter(blog=b.id)  # Query using id from instance
    Entry.objects.filter(blog=5)  # Query using id directly

## Återgår till rå SQL

Om du behöver skriva en SQL-fråga som är för komplex för Djangos databasmappare att hantera, kan du falla tillbaka på att skriva SQL för hand. Django har ett par alternativ för att skriva råa SQL-frågor; se Utföra SQL-frågor i råformat.

Slutligen är det viktigt att notera att Djangos databaslager bara är ett gränssnitt till din databas. Du kan komma åt din databas via andra verktyg, programmeringsspråk eller databasramverk; det finns inget Django-specifikt med din databas.