API-referens för uppslagning

Det här dokumentet innehåller API-referenser för lookups, Djangos API för att bygga WHERE-klausulen i en databasfråga. För att lära dig hur du använder lookups, se Göra förfrågningar; för att lära dig hur du skapar nya lookups, se Hur man skriver anpassade uppslagsord.

Lookup API har två komponenter: en RegisterLookupMixin-klass som registrerar lookups, och Query Expression API, en uppsättning metoder som en klass måste implementera för att kunna registreras som en lookup.

Django har två basklasser som följer API:et för frågeuttryck och från vilka alla Djangos inbyggda uppslagsord härleds:

  • Lookup: för att slå upp ett fält (t.ex. exakt av field_name__exact)

  • Transform: för att transformera ett fält

Ett lookup-uttryck består av tre delar:

  • Fältdel (t.ex. Book.objects.filter(author__best_friends__first_name...);

  • Transformerar del (kan utelämnas) (t.ex. __lower__first3chars__reversed);

  • En uppslagning (t.ex. __icontains) som, om den utelämnas, har __exact som standard.

API för registrering

Django använder RegisterLookupMixin för att ge en klass gränssnittet för att registrera lookups på sig själv eller dess instanser. De två mest framträdande exemplen är Field, basklassen för alla modellfält, och Transform, basklassen för alla Django-transformationer.

class lookups.RegisterLookupMixin

En mixin som implementerar API:et för uppslagning i en klass.

classmethod register_lookup(lookup, lookup_name=None)

Registrerar en ny uppslagning i klassen eller klassinstansen. Till exempel:

DateField.register_lookup(YearExact)
User._meta.get_field("date_joined").register_lookup(MonthExact)

kommer att registrera YearExact lookup på DateField och MonthExact lookup på User.date_joined (du kan använda :ref:Field Access API <model-meta-field-api> för att hämta en enda fältinstans). Den åsidosätter en lookup som redan finns med samma namn. Uppslagningar som registrerats på fältinstanser har företräde framför de uppslagningar som registrerats på klasser. lookup_name kommer att användas för denna lookup om det anges, annars kommer lookup.lookup_name att användas.

get_lookup(lookup_name)

Returnerar den Lookup med namnet lookup_name som registrerats i klassen eller klassinstansen beroende på vad som anropar den. Standardimplementeringen tittar rekursivt på alla överordnade klasser och kontrollerar om någon har en registrerad uppslagning med namnet lookup_name, och returnerar den första matchningen. Instansuppslagningar skulle åsidosätta alla klassuppslagningar med samma lookup_name.

get_lookups()

Returnerar en ordbok över varje uppslagsnamn som registrerats i den klass eller klassinstans som mappats till klassen Lookup.

get_transform(transform_name)

Returnerar en Transform med namnet transform_name som är registrerad i klassen eller klassinstansen. Standardimplementeringen tittar rekursivt på alla överordnade klasser för att kontrollera om någon har den registrerade transformationen med namnet transform_name, och returnerar den första matchningen.

För att en klass ska vara en lookup måste den följa :ref:Query Expression API <query-expression>. Lookup och Transform följer naturligtvis detta API.

API för frågeuttryck

API:et för frågeuttryck är en gemensam uppsättning metoder som klasser definierar för att kunna användas i frågeuttryck för att översätta dem till SQL-uttryck. Direkta fältreferenser, aggregat och Transform är exempel som följer detta API. En klass sägs följa API:et för frågeuttryck när den implementerar följande metoder:

as_sql(compiler, connection)

Genererar SQL-fragmentet för uttrycket. Returnerar en tupel (sql, params), där sql är SQL-strängen och params är listan eller tupeln av frågeparametrar. `` Compiler`` är ett SQLCompiler-objekt, som har en compile()-metod som kan användas för att sammanställa andra uttryck. `` Connection`` är anslutningen som används för att köra frågan.

Att anropa expression.as_sql() är vanligtvis felaktigt - istället bör compiler.compile(expression) användas. Metoden compiler.compile() kommer att ta hand om anrop av leverantörsspecifika metoder för uttrycket.

Anpassade nyckelordsargument kan definieras för denna metod om det är troligt att as_vendorname()-metoder eller underklasser kommer att behöva tillhandahålla data för att åsidosätta genereringen av SQL-strängen. Se Func.as_sql() för exempel på användning.

as_vendorname(compiler, connection)

Fungerar som metoden as_sql(). När ett uttryck kompileras av compiler.compile(), kommer Django först att försöka anropa as_vendorname(), där vendorname är leverantörsnamnet på den backend som används för att utföra frågan. vendorname är ett av postgresql, oracle, sqlite eller mysql för Djangos inbyggda backends.

get_lookup(lookup_name)

Måste returnera lookupen med namnet lookup_name. Till exempel: genom att returnera self.output_field.get_lookup(lookup_name).

get_transform(transform_name)

Måste returnera uppslagningen med namnet transform_name. Till exempel: genom att returnera self.output_field.get_transform(transform_name).

output_field

Definierar typen av klass som returneras av metoden get_lookup(). Det måste vara en Field-instans.

Transform referens

class Transform[source]

En Transform är en generisk klass för att implementera fälttransformationer. Ett framträdande exempel är __year som omvandlar en DateField till en IntegerField.

Notationen för att använda en Transform i ett lookup-uttryck är <expression>__<transformation> (t.ex. date__year).

Den här klassen följer Query Expression API, vilket innebär att du kan använda <expression>__<transform1>__<transform2>. Det är ett specialiserat Func()-uttryck som bara accepterar ett argument. Det kan också användas på höger sida av ett filter eller direkt som en annotation.

bilateral

En boolean som anger om denna transformation ska tillämpas på både lhs och rhs. Bilaterala transformationer kommer att tillämpas på rhs i samma ordning som de förekommer i uppslagsuttrycket. Som standard är den inställd på False. För exempel på användning, se Hur man skriver anpassade uppslagsord.

lhs[source]

Den vänstra sidan - det som transformeras. Det måste följa :ref:``Query Expression API <query-expression>`.

lookup_name

Namnet på uppslagsobjektet, som används för att identifiera det vid analys av frågeuttryck. Det kan inte innehålla strängen "__".

output_field

Definierar den klass som denna transformation matar ut. Det måste vara en Field-instans. Som standard är den samma som dess lhs.output_field.

Lookup referens

class Lookup[source]

En Lookup är en generisk klass för att implementera uppslagningar. En lookup är ett frågeuttryck med en vänstersida, lhs; en högersida, rhs; och ett lookup_name som används för att producera en boolesk jämförelse mellan lhs och rhs såsom lhs in rhs eller lhs > rhs.

Den primära notationen för att använda en lookup i ett uttryck är <lhs>__<lookup_name>=<rhs>. Lookups kan också användas direkt i QuerySet-filter:

Book.objects.filter(LessThan(F("word_count"), 7500))

…eller anteckningar:

Book.objects.annotate(is_short_story=LessThan(F("word_count"), 7500))
lhs

Den vänstra sidan - det som söks upp. Objektet följer vanligtvis :ref:``Query Expression API <query-expression>`. Det kan också vara ett vanligt värde.

rhs

Den högra sidan - det som lhs jämförs med. Det kan vara ett vanligt värde eller något som kompileras till SQL, vanligtvis ett F()-objekt eller en QuerySet.

lookup_name

Namnet på den här uppslagningen, som används för att identifiera den vid analys av frågeuttryck. Det kan inte innehålla strängen "__".

prepare_rhs

Standardvärdet är True. När rhs är ett vanligt värde avgör prepare_rhs om det ska förberedas för att användas som en parameter i en fråga. För att göra detta anropas lhs.output_field.get_prep_value() om det är definierat, eller så omsluts rhs av Value() annars.

process_lhs(compiler, connection, lhs=None)[source]

Returnerar en tupel (lhs_string, lhs_params), som returneras av compiler.compile(lhs). Denna metod kan åsidosättas för att ställa in hur lhs bearbetas.

compiler är ett SQLCompiler objekt, som ska användas som compiler.compile(lhs) för att sammanställa lhs. connection kan användas för att sammanställa leverantörsspecifik SQL. Om lhs inte är None, använd den som den bearbetade lhs istället för self.lhs.

process_rhs(compiler, connection)[source]

Uppträder på samma sätt som process_lhs(), för den högra sidan.