{"title":"Hur man skriver anpassade uppslagsord","version":"6.0","locale":"sv","docname":"howto/custom-lookups","url":"/sv/6.0/howto/custom-lookups/","canonical":"https://djangodocs.dev/sv/6.0/howto/custom-lookups/","summary":"Django erbjuder ett brett utbud av inbyggda uppslagsord för filtrering (till exempel exakt och innehåller ). Denna dokumentation förklarar hur man skriver anpassade…","html":"<h1>Hur man skriver anpassade uppslagsord<a class=\"heading-anchor\" href=\"#how-to-write-custom-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django erbjuder ett brett utbud av <a class=\"reference internal\" href=\"/sv/6.0/ref/models/querysets/#field-lookups\"><span class=\"std std-ref\">inbyggda uppslagsord</span></a> för filtrering (till exempel <code class=\"docutils literal notranslate\"><span class=\"pre\">exakt</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">innehåller</span></code>). Denna dokumentation förklarar hur man skriver anpassade uppslagsord och hur man ändrar funktionen hos befintliga uppslagsord. För API-referenser för uppslagsord, se <a class=\"reference internal\" href=\"/sv/6.0/ref/models/lookups/\"><span class=\"doc\">API-referens för uppslagning</span></a>.</p>\n<section id=\"a-lookup-example\">\n<h2>Ett exempel på uppslagning<a class=\"heading-anchor\" href=\"#a-lookup-example\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Låt oss börja med en liten anpassad uppslagning. Vi kommer att skriva en anpassad lookup <code class=\"docutils literal notranslate\"><span class=\"pre\">ne</span></code> som fungerar motsatt till <code class=\"docutils literal notranslate\"><span class=\"pre\">exact</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">Author.objects.filter(name__ne='Jack')</span></code> kommer att översättas till SQL:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"ss\">&quot;author&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;name&quot;</span><span class=\"w\"> </span><span class=\"o\">&lt;&gt;</span><span class=\"w\"> </span><span class=\"s1\">&#39;Jack&#39;</span>\n</code></pre></div>\n<p>Denna SQL är oberoende av backend, så vi behöver inte oroa oss för olika databaser.</p>\n<p>Det finns två steg för att få detta att fungera. Först måste vi implementera uppslagningen, sedan måste vi berätta för Django om den:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Lookup</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">NotEqual</span><span class=\"p\">(</span><span class=\"n\">Lookup</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;ne&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_sql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n        <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">lhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_lhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">rhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_rhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;</span><span class=\"si\">%s</span><span class=\"s2\"> &lt;&gt; </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">),</span> <span class=\"n\">params</span>\n</code></pre></div>\n<p>För att registrera <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code>-uppslaget måste vi anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">register_lookup</span></code> på den fältklass som vi vill att uppslaget ska vara tillgängligt för. I det här fallet är uppslaget meningsfullt för alla underklasser till <code class=\"docutils literal notranslate\"><span class=\"pre\">Field</span></code>, så vi registrerar det med <code class=\"docutils literal notranslate\"><span class=\"pre\">Field</span></code> direkt:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Field</span>\n\n<span class=\"n\">Field</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">NotEqual</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Registrering av uppslag kan också göras med hjälp av ett dekoratormönster:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Field</span>\n\n\n<span class=\"nd\">@Field</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">NotEqualLookup</span><span class=\"p\">(</span><span class=\"n\">Lookup</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Vi kan nu använda <code class=\"docutils literal notranslate\"><span class=\"pre\">foo__ne</span></code> för alla fält <code class=\"docutils literal notranslate\"><span class=\"pre\">foo</span></code>. Du måste se till att denna registrering sker innan du försöker skapa några frågeuppsättningar med hjälp av den. Du kan placera implementationen i en <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code>-fil, eller registrera uppslagningen i <code class=\"docutils literal notranslate\"><span class=\"pre\">ready()</span></code>-metoden i en <code class=\"docutils literal notranslate\"><span class=\"pre\">AppConfig</span></code>.</p>\n<p>Om man tittar närmare på implementationen är det första obligatoriska attributet <code class=\"docutils literal notranslate\"><span class=\"pre\">lookup_name</span></code>. Detta gör det möjligt för ORM att förstå hur man tolkar <code class=\"docutils literal notranslate\"><span class=\"pre\">name__ne</span></code> och använda <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> för att generera SQL. Enligt konvention är dessa namn alltid gemena strängar som bara innehåller bokstäver, men det enda hårda kravet är att det inte får innehålla strängen <code class=\"docutils literal notranslate\"><span class=\"pre\">__</span></code>.</p>\n<p>Vi måste sedan definiera metoden <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql</span></code>. Detta tar ett <code class=\"docutils literal notranslate\"><span class=\"pre\">SQLCompiler</span></code>-objekt, kallat <code class=\"docutils literal notranslate\"><span class=\"pre\">compiler</span></code>, och den aktiva databasanslutningen. <code class=\"docutils literal notranslate\"><span class=\"pre\">SQLCompiler</span></code> -objekt är inte dokumenterade, men det enda vi behöver veta om dem är att de har en <code class=\"docutils literal notranslate\"><span class=\"pre\">compile()</span> <span class=\"pre\">``</span> <span class=\"pre\">-metod</span> <span class=\"pre\">som</span> <span class=\"pre\">returnerar</span> <span class=\"pre\">en</span> <span class=\"pre\">tuple</span> <span class=\"pre\">som</span> <span class=\"pre\">innehåller</span> <span class=\"pre\">en</span> <span class=\"pre\">SQL-sträng</span> <span class=\"pre\">och</span> <span class=\"pre\">parametrarna</span> <span class=\"pre\">som</span> <span class=\"pre\">ska</span> <span class=\"pre\">interpoleras</span> <span class=\"pre\">i</span> <span class=\"pre\">den</span> <span class=\"pre\">strängen.</span> <span class=\"pre\">I</span> <span class=\"pre\">de</span> <span class=\"pre\">flesta</span> <span class=\"pre\">fall</span> <span class=\"pre\">behöver</span> <span class=\"pre\">du</span> <span class=\"pre\">inte</span> <span class=\"pre\">använda</span> <span class=\"pre\">den</span> <span class=\"pre\">direkt</span> <span class=\"pre\">utan</span> <span class=\"pre\">kan</span> <span class=\"pre\">skicka</span> <span class=\"pre\">den</span> <span class=\"pre\">vidare</span> <span class=\"pre\">till</span> <span class=\"pre\">``process_lhs()</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">process_rhs()</span></code>.</p>\n<p>En <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> arbetar mot två värden, <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">rhs</span></code>, som står för vänster sida och höger sida. Den vänstra sidan är vanligtvis en fältreferens, men det kan vara vad som helst som implementerar <a class=\"reference internal\" href=\"/sv/6.0/ref/models/lookups/#query-expression\"><span class=\"std std-ref\">query expression API</span></a>. Den högra sidan är det värde som användaren anger. I exemplet <code class=\"docutils literal notranslate\"><span class=\"pre\">Author.objects.filter(name__ne='Jack')</span></code> är vänstersidan en referens till fältet <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> i modellen <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">'Jack'</span></code> är högersidan.</p>\n<p>Vi kallar <code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">process_rhs</span></code> för att konvertera dem till de värden vi behöver för SQL med hjälp av <code class=\"docutils literal notranslate\"><span class=\"pre\">compiler</span></code>-objektet som beskrivs tidigare. Dessa metoder returnerar tuples som innehåller SQL och de parametrar som ska interpoleras till SQL, precis som vi behöver returnera från vår <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql</span></code>-metod. I exemplet ovan returnerar <code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs</span></code> <code class=\"docutils literal notranslate\"><span class=\"pre\">('&quot;author&quot;.&quot;name&quot;',</span> <span class=\"pre\">[])</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">process_rhs</span></code> returnerar <code class=\"docutils literal notranslate\"><span class=\"pre\">('&quot;%s&quot;',</span> <span class=\"pre\">['Jack'])</span></code>. I det här exemplet fanns det inga parametrar för den vänstra sidan, men det beror på vilket objekt vi har, så vi måste fortfarande inkludera dem i de parametrar vi returnerar.</p>\n<p>Slutligen kombinerar vi delarna till ett SQL-uttryck med <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;&gt;</span></code> och anger alla parametrar för frågan. Vi returnerar sedan en tupel som innehåller den genererade SQL-strängen och parametrarna.</p>\n</section>\n<section id=\"a-transformer-example\">\n<h2>Ett exempel på en transformator<a class=\"heading-anchor\" href=\"#a-transformer-example\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Den anpassade lookupen ovan är bra, men i vissa fall kanske du vill kunna kedja ihop lookups. Låt oss till exempel anta att vi bygger en applikation där vi vill använda operatören <code class=\"docutils literal notranslate\"><span class=\"pre\">abs()</span></code>. Vi har en <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment</span></code>-modell som registrerar ett startvärde, slutvärde och förändringen (start - slut). Vi skulle vilja hitta alla experiment där förändringen var lika med ett visst belopp (<code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs=27)</span></code>), eller där den inte översteg ett visst belopp (<code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs__lt=27)</span></code>).</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>Detta exempel är något konstruerat, men det visar på ett bra sätt hur många funktioner som är möjliga på ett sätt som är oberoende av databasens backend, och utan att duplicera funktioner som redan finns i Django.</p>\n</aside>\n<p>Vi börjar med att skriva en transformator för <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code>. Detta kommer att använda SQL-funktionen <code class=\"docutils literal notranslate\"><span class=\"pre\">ABS()</span></code> för att omvandla värdet före jämförelse:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Transform</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AbsoluteValue</span><span class=\"p\">(</span><span class=\"n\">Transform</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;abs&quot;</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;ABS&quot;</span>\n</code></pre></div>\n<p>Låt oss sedan registrera den för <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">IntegerField</span>\n\n<span class=\"n\">IntegerField</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">AbsoluteValue</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Vi kan nu köra de frågor vi hade tidigare. <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs=27)</span></code> kommer att generera följande SQL:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"p\">...</span><span class=\"w\"> </span><span class=\"k\">WHERE</span><span class=\"w\"> </span><span class=\"k\">ABS</span><span class=\"p\">(</span><span class=\"ss\">&quot;experiments&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;change&quot;</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"mi\">27</span>\n</code></pre></div>\n<p>Genom att använda <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> istället för <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> innebär det att vi kan kedja ytterligare uppslagningar efteråt. Så <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs__lt=27)</span></code> kommer att generera följande SQL:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"p\">...</span><span class=\"w\"> </span><span class=\"k\">WHERE</span><span class=\"w\"> </span><span class=\"k\">ABS</span><span class=\"p\">(</span><span class=\"ss\">&quot;experiments&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;change&quot;</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">27</span>\n</code></pre></div>\n<p>Observera att om det inte finns någon annan uppslagning angiven, tolkar Django <code class=\"docutils literal notranslate\"><span class=\"pre\">change__abs=27</span></code> som <code class=\"docutils literal notranslate\"><span class=\"pre\">change__abs__exact=27</span></code>.</p>\n<p>Detta gör också att resultatet kan användas i klausulerna <code class=\"docutils literal notranslate\"><span class=\"pre\">ORDER</span> <span class=\"pre\">BY</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">DISTINCT</span> <span class=\"pre\">ON</span></code>. Till exempel genererar <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.order_by('change__abs')</span></code>:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"p\">...</span><span class=\"w\"> </span><span class=\"k\">ORDER</span><span class=\"w\"> </span><span class=\"k\">BY</span><span class=\"w\"> </span><span class=\"k\">ABS</span><span class=\"p\">(</span><span class=\"ss\">&quot;experiments&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;change&quot;</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"k\">ASC</span>\n</code></pre></div>\n<p>Och på databaser som stöder distinkta på fält (som PostgreSQL) genererar <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.distinct('change__abs')</span></code>:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"p\">...</span><span class=\"w\"> </span><span class=\"k\">DISTINCT</span><span class=\"w\"> </span><span class=\"k\">ON</span><span class=\"w\"> </span><span class=\"k\">ABS</span><span class=\"p\">(</span><span class=\"ss\">&quot;experiments&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;change&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>När Django letar efter vilka uppslagningar som är tillåtna efter att <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> har tillämpats använder Django attributet <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code>. Vi behöver inte ange detta här eftersom det inte ändras, men om vi antar att vi tillämpar <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> på ett fält som representerar en mer komplex typ (till exempel en punkt i förhållande till ett ursprung eller ett komplext tal), kanske vi vill ange att transformationen returnerar en <code class=\"docutils literal notranslate\"><span class=\"pre\">FloatField</span></code>-typ för ytterligare uppslagningar. Detta kan göras genom att lägga till ett <code class=\"docutils literal notranslate\"><span class=\"pre\">output_field</span></code>-attribut till transform:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">FloatField</span><span class=\"p\">,</span> <span class=\"n\">Transform</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AbsoluteValue</span><span class=\"p\">(</span><span class=\"n\">Transform</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;abs&quot;</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;ABS&quot;</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">output_field</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">FloatField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Detta säkerställer att ytterligare uppslagningar som <code class=\"docutils literal notranslate\"><span class=\"pre\">abs__lte</span></code> beter sig som de skulle göra för en <code class=\"docutils literal notranslate\"><span class=\"pre\">FloatField</span></code>.</p>\n</section>\n<section id=\"writing-an-efficient-abs-lt-lookup\">\n<h2>Skriva en effektiv <code class=\"docutils literal notranslate\"><span class=\"pre\">abs__lt</span></code>-uppslagning<a class=\"heading-anchor\" href=\"#writing-an-efficient-abs-lt-lookup\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>När man använder den ovan skrivna <code class=\"docutils literal notranslate\"><span class=\"pre\">abs</span></code>-uppslagningen kommer den SQL som produceras inte att använda index effektivt i vissa fall. I synnerhet när vi använder <code class=\"docutils literal notranslate\"><span class=\"pre\">change__abs__lt=27</span></code>, är detta likvärdigt med <code class=\"docutils literal notranslate\"><span class=\"pre\">change__gt=-27</span></code> AND <code class=\"docutils literal notranslate\"><span class=\"pre\">change__lt=27</span></code>. (För <code class=\"docutils literal notranslate\"><span class=\"pre\">lte</span></code>-fallet kan vi använda SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">BETWEEN</span></code>).</p>\n<p>Så vi vill att <code class=\"docutils literal notranslate\"><span class=\"pre\">Experiment.objects.filter(change__abs__lt=27)</span></code> ska generera följande SQL:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"p\">..</span><span class=\"w\"> </span><span class=\"k\">WHERE</span><span class=\"w\"> </span><span class=\"ss\">&quot;experiments&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;change&quot;</span><span class=\"w\"> </span><span class=\"o\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">27</span><span class=\"w\"> </span><span class=\"k\">AND</span><span class=\"w\"> </span><span class=\"ss\">&quot;experiments&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;change&quot;</span><span class=\"w\"> </span><span class=\"o\">&gt;</span><span class=\"w\"> </span><span class=\"o\">-</span><span class=\"mi\">27</span>\n</code></pre></div>\n<p>Genomförandet är:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Lookup</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AbsoluteValueLessThan</span><span class=\"p\">(</span><span class=\"n\">Lookup</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;lt&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_sql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">):</span>\n        <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">lhs_params</span> <span class=\"o\">=</span> <span class=\"n\">compiler</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lhs</span><span class=\"o\">.</span><span class=\"n\">lhs</span><span class=\"p\">)</span>\n        <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">rhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_rhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span> <span class=\"o\">+</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;</span><span class=\"si\">%s</span><span class=\"s2\"> &lt; </span><span class=\"si\">%s</span><span class=\"s2\"> AND </span><span class=\"si\">%s</span><span class=\"s2\"> &gt; -</span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">),</span> <span class=\"n\">params</span>\n\n\n<span class=\"n\">AbsoluteValue</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">AbsoluteValueLessThan</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Det finns ett par anmärkningsvärda saker som händer. För det första anropar inte <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValueLessThan</span></code> <code class=\"docutils literal notranslate\"><span class=\"pre\">process_lhs()</span></code>. Istället hoppar den över omvandlingen av <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> som görs av <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> och använder den ursprungliga <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code>. Det vill säga, vi vill få fram <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;experiments&quot;.&quot;change&quot;</span></code> inte <code class=\"docutils literal notranslate\"><span class=\"pre\">ABS(&quot;experiments&quot;.&quot;change&quot;)</span></code>. Att referera direkt till <code class=\"docutils literal notranslate\"><span class=\"pre\">self.lhs.lhs</span></code> är säkert eftersom <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValueLessThan</span></code> endast kan nås från <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> lookup, det vill säga <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> är alltid en instans av <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code>.</p>\n<p>Observera också att eftersom båda sidorna används flera gånger i frågan måste params innehålla <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs_params</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">rhs_params</span></code> flera gånger.</p>\n<p>Den sista frågan gör inversionen (<code class=\"docutils literal notranslate\"><span class=\"pre\">27</span></code> till <code class=\"docutils literal notranslate\"><span class=\"pre\">-27</span></code>) direkt i databasen. Anledningen till att vi gör detta är att om <code class=\"docutils literal notranslate\"><span class=\"pre\">self.rhs</span></code> är något annat än ett vanligt heltalsvärde (till exempel en <code class=\"docutils literal notranslate\"><span class=\"pre\">F()</span></code>-referens) kan vi inte göra omvandlingarna i Python.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>Faktum är att de flesta lookups med <code class=\"docutils literal notranslate\"><span class=\"pre\">__abs</span></code> kan implementeras som intervallfrågor som detta, och på de flesta databasbackends är det troligtvis mer förnuftigt att göra det eftersom du kan använda indexen. Men med PostgreSQL kanske du vill lägga till ett index på <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>abs (change) `` vilket gör att dessa frågor kan vara mycket effektiva.</p>\n</aside>\n</section>\n<section id=\"a-bilateral-transformer-example\">\n<h2>Ett exempel på en bilateral transformator<a class=\"heading-anchor\" href=\"#a-bilateral-transformer-example\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Exemplet <code class=\"docutils literal notranslate\"><span class=\"pre\">AbsoluteValue</span></code> som vi diskuterade tidigare är en transformation som gäller för den vänstra sidan av uppslagningen. Det kan finnas vissa fall där du vill att transformationen ska tillämpas på både vänster och höger sida. Till exempel om du vill filtrera en frågeuppsättning baserat på likheten mellan vänster och höger sida utan hänsyn till någon SQL-funktion.</p>\n<p>Låt oss undersöka skiftlägesokänsliga transformationer här. Denna omvandling är inte särskilt användbar i praktiken eftersom Django redan har ett gäng inbyggda skiftlägesokänsliga uppslagningar, men det kommer att vara en trevlig demonstration av bilaterala omvandlingar på ett databasagnostiskt sätt.</p>\n<p>Vi definierar en <code class=\"docutils literal notranslate\"><span class=\"pre\">UpperCase</span></code>-transformator som använder SQL-funktionen <code class=\"docutils literal notranslate\"><span class=\"pre\">UPPER()</span></code> för att omvandla värdena före jämförelse. Vi definierar <a class=\"reference internal\" href=\"/sv/6.0/ref/models/lookups/#django.db.models.Transform.bilateral\" title=\"django.db.models.Transform.bilateral\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">bilateral</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code></a> för att ange att denna omvandling ska gälla för både <code class=\"docutils literal notranslate\"><span class=\"pre\">lhs</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">rhs</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Transform</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UpperCase</span><span class=\"p\">(</span><span class=\"n\">Transform</span><span class=\"p\">):</span>\n    <span class=\"n\">lookup_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;upper&quot;</span>\n    <span class=\"n\">function</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;UPPER&quot;</span>\n    <span class=\"n\">bilateral</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>Nu ska vi registrera den:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">CharField</span><span class=\"p\">,</span> <span class=\"n\">TextField</span>\n\n<span class=\"n\">CharField</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">UpperCase</span><span class=\"p\">)</span>\n<span class=\"n\">TextField</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">UpperCase</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Nu kommer frågeuppsättningen <code class=\"docutils literal notranslate\"><span class=\"pre\">Author.objects.filter(name__upper=&quot;doe&quot;)</span></code> att generera en skiftlägeskänslig fråga så här:</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">SELECT</span><span class=\"w\"> </span><span class=\"p\">...</span><span class=\"w\"> </span><span class=\"k\">WHERE</span><span class=\"w\"> </span><span class=\"k\">UPPER</span><span class=\"p\">(</span><span class=\"ss\">&quot;author&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;name&quot;</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"k\">UPPER</span><span class=\"p\">(</span><span class=\"s1\">&#39;doe&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"writing-alternative-implementations-for-existing-lookups\">\n<h2>Skriva alternativa implementationer för befintliga uppslagningar<a class=\"heading-anchor\" href=\"#writing-alternative-implementations-for-existing-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ibland kräver olika databasleverantörer olika SQL för samma operation. I det här exemplet kommer vi att skriva om en anpassad implementering för MySQL för operatorn NotEqual. Istället för <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;&gt;</span></code> kommer vi att använda operatorn <code class=\"docutils literal notranslate\"><span class=\"pre\">!=</span></code>. (Observera att i verkligheten stöder nästan alla databaser båda, inklusive alla officiella databaser som stöds av Django).</p>\n<p>Vi kan ändra beteendet på en specifik backend genom att skapa en subklass av <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> med en <code class=\"docutils literal notranslate\"><span class=\"pre\">as_mysql</span></code>-metod:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MySQLNotEqual</span><span class=\"p\">(</span><span class=\"n\">NotEqual</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">as_mysql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">extra_context</span><span class=\"p\">):</span>\n        <span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">lhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_lhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">rhs</span><span class=\"p\">,</span> <span class=\"n\">rhs_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">process_rhs</span><span class=\"p\">(</span><span class=\"n\">compiler</span><span class=\"p\">,</span> <span class=\"n\">connection</span><span class=\"p\">)</span>\n        <span class=\"n\">params</span> <span class=\"o\">=</span> <span class=\"n\">lhs_params</span> <span class=\"o\">+</span> <span class=\"n\">rhs_params</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;</span><span class=\"si\">%s</span><span class=\"s2\"> != </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">lhs</span><span class=\"p\">,</span> <span class=\"n\">rhs</span><span class=\"p\">),</span> <span class=\"n\">params</span>\n\n\n<span class=\"n\">Field</span><span class=\"o\">.</span><span class=\"n\">register_lookup</span><span class=\"p\">(</span><span class=\"n\">MySQLNotEqual</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Vi kan sedan registrera den med <code class=\"docutils literal notranslate\"><span class=\"pre\">Field</span></code>. Den ersätter den ursprungliga klassen <code class=\"docutils literal notranslate\"><span class=\"pre\">NotEqual</span></code> eftersom den har samma <code class=\"docutils literal notranslate\"><span class=\"pre\">lookup_name</span></code>.</p>\n<p>När en fråga sammanställs letar Django först efter <code class=\"docutils literal notranslate\"><span class=\"pre\">as_%s</span> <span class=\"pre\">%</span> <span class=\"pre\">connection.vendor</span></code>-metoder och faller sedan tillbaka till <code class=\"docutils literal notranslate\"><span class=\"pre\">as_sql</span></code>. Leverantörsnamnen för de inbyggda backends är <code class=\"docutils literal notranslate\"><span class=\"pre\">qlite</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">postgresql</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">oracle</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">mysql</span></code>.</p>\n</section>\n<section id=\"how-django-determines-the-lookups-and-transforms-which-are-used\">\n<h2>Hur Django bestämmer vilka lookups och transformationer som ska användas<a class=\"heading-anchor\" href=\"#how-django-determines-the-lookups-and-transforms-which-are-used\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>I vissa fall kanske du dynamiskt vill ändra vilken <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> eller <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> som returneras baserat på det namn som skickas in, snarare än att fixa det. Som ett exempel kan du ha ett fält som lagrar koordinater eller en godtycklig dimension, och vill tillåta en syntax som <code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(coords__x7=4)</span></code> för att returnera de objekt där den 7:e koordinaten har värdet 4. För att göra detta skulle du åsidosätta <code class=\"docutils literal notranslate\"><span class=\"pre\">get_lookup</span></code> med något liknande:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CoordinatesField</span><span class=\"p\">(</span><span class=\"n\">Field</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_lookup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">lookup_name</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"n\">lookup_name</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s2\">&quot;x&quot;</span><span class=\"p\">):</span>\n            <span class=\"k\">try</span><span class=\"p\">:</span>\n                <span class=\"n\">dimension</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">lookup_name</span><span class=\"o\">.</span><span class=\"n\">removeprefix</span><span class=\"p\">(</span><span class=\"s2\">&quot;x&quot;</span><span class=\"p\">))</span>\n            <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n                <span class=\"k\">pass</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"n\">get_coordinate_lookup</span><span class=\"p\">(</span><span class=\"n\">dimension</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_lookup</span><span class=\"p\">(</span><span class=\"n\">lookup_name</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Du skulle då definiera <code class=\"docutils literal notranslate\"><span class=\"pre\">get_coordinate_lookup</span></code> på lämpligt sätt för att returnera en <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> subklass som hanterar det relevanta värdet av <code class=\"docutils literal notranslate\"><span class=\"pre\">dimension</span></code>.</p>\n<p>Det finns en metod med liknande namn som heter <code class=\"docutils literal notranslate\"><span class=\"pre\">get_transform()</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">get_lookup()</span></code> skall alltid returnera en <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> subklass, och <code class=\"docutils literal notranslate\"><span class=\"pre\">get_transform()</span></code> en <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> subklass. Det är viktigt att komma ihåg att <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code>-objekt kan filtreras ytterligare, medan <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code>-objekt inte kan det.</p>\n<p>Vid filtrering, om det bara finns ett uppslagsnamn kvar att lösa, letar vi efter en <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code>. Om det finns flera namn letar vi efter en <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code>. Om det bara finns ett namn och ingen <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code> hittas, letar vi efter en <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code> och sedan den <code class=\"docutils literal notranslate\"><span class=\"pre\">exakta</span></code> lookupen på den <code class=\"docutils literal notranslate\"><span class=\"pre\">Transform</span></code>. Alla anropssekvenser slutar alltid med en <code class=\"docutils literal notranslate\"><span class=\"pre\">Lookup</span></code>. För att förtydliga:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(myfield__mylookup)</span></code> kommer att anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_lookup('mylookup')</span></code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(myfield__mytransform__mylookup)</span></code> kommer att anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_transform('mytransform')</span></code> och sedan <code class=\"docutils literal notranslate\"><span class=\"pre\">mytransform.get_lookup('mylookup')</span></code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">.filter(myfield__mytransform)</span></code> kommer först att anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_lookup('mytransform')</span></code>, vilket kommer att misslyckas, så det kommer att falla tillbaka till att anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">myfield.get_transform('mytransform')</span></code> och sedan <code class=\"docutils literal notranslate\"><span class=\"pre\">mytransform.get_lookup('exact')</span></code>.</p></li>\n</ul>\n</section>","rootId":"how-to-write-custom-lookups","toc":[{"title":"Ett exempel på uppslagning","anchor":"a-lookup-example","children":[]},{"title":"Ett exempel på en transformator","anchor":"a-transformer-example","children":[]},{"title":"Skriva en effektiv abs__lt-uppslagning","anchor":"writing-an-efficient-abs-lt-lookup","children":[]},{"title":"Ett exempel på en bilateral transformator","anchor":"a-bilateral-transformer-example","children":[]},{"title":"Skriva alternativa implementationer för befintliga uppslagningar","anchor":"writing-alternative-implementations-for-existing-lookups","children":[]},{"title":"Hur Django bestämmer vilka lookups och transformationer som ska användas","anchor":"how-django-determines-the-lookups-and-transforms-which-are-used","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Hur man gör-guider","url":"/sv/6.0/howto/"}],"prev":{"docname":"howto/writing-migrations","title":"Så här skapar du databasmigreringar","url":"/sv/6.0/howto/writing-migrations/"},"next":{"docname":"howto/outputting-csv","title":"Hur man skapar CSV-utdata","url":"/sv/6.0/howto/outputting-csv/"},"formats":{"html":"/sv/6.0/howto/custom-lookups/","markdown":"/sv/6.0/howto/custom-lookups.md","json":"/sv/6.0/howto/custom-lookups.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/howto/custom-lookups.txt","official":"https://docs.djangoproject.com/sv/6.0/howto/custom-lookups/","inVersions":["6.1","6.0","5.2"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}