# Django 6.0.7 documentation

# URL-distributör

Ett rent och elegant URL-schema är en viktig detalj i en högkvalitativ webbapplikation. Med Django kan du designa webbadresser hur du vill, utan några begränsningar av ramverket.

Se ”Cool URIs don’t change” av Tim Berners-Lee, skaparen av World Wide Web, för utmärkta argument för varför webbadresser ska vara rena och användbara.

## Översikt

För att utforma webbadresser för en app skapar du en Python-modul som informellt kallas URLconf (URL-konfiguration). Den här modulen är ren Python-kod och är en mappning mellan URL-sökvägsuttryck till Python-funktioner (dina vyer).

Denna mappning kan vara så kort eller så lång som behövs. Den kan referera till andra mappningar. Och eftersom det är ren Python-kod kan den konstrueras dynamiskt.

Django tillhandahåller också ett sätt att översätta webbadresser enligt det aktiva språket. Se internationaliseringsdokumentation för mer information.

## Hur Django behandlar en förfrågan

När en användare begär en sida från din Django-drivna webbplats är detta den algoritm som systemet följer för att avgöra vilken Python-kod som ska köras:

1. Django bestämmer vilken URLconf-modul som ska användas. Vanligtvis är detta värdet på `ROOT_URLCONF`-inställningen, men om det inkommande `HttpRequest`-objektet har ett `urlconf`-attribut (inställt av middleware), kommer dess värde att användas i stället för `ROOT_URLCONF`-inställningen.

2. Django laddar den Python-modulen och letar efter variabeln `urlpatterns`. Detta bör vara en sequence av `django.urls.path()` och/eller `django.urls.re_path()` instanser.

3. Django går igenom varje URL-mönster, i ordning, och stannar vid det första som matchar den begärda URL:en och matchar mot `path_info`.

4. När ett av URL-mönstren matchar importerar och anropar Django den angivna vyn, som är en Python-funktion (eller en klassbaserad vy). Vyn får följande argument:

   - En instans av `HttpRequest`.

   - Om det matchade URL-mönstret inte innehåller några namngivna grupper anges matchningarna från det reguljära uttrycket som positionsargument.

   - Nyckelordsargumenten består av alla namngivna delar som matchas av sökvägsuttrycket som tillhandahålls, åsidosatta av alla argument som anges i det valfria `kwargs`-argumentet till `django.urls.path()` eller `django.urls.re_path()`.

5. Om inget URL-mönster matchar, eller om ett undantag uppstår under någon punkt i denna process, anropar Django en lämplig felhanteringsvy. Se Felhantering nedan.

## Exempel

Här är ett exempel på URLconf:

    from django.urls import path

    from . import views

    urlpatterns = [
        path("articles/2003/", views.special_case_2003),
        path("articles/<int:year>/", views.year_archive),
        path("articles/<int:year>/<int:month>/", views.month_archive),
        path("articles/<int:year>/<int:month>/<slug:slug>/", views.article_detail),
    ]

Anteckningar:

- Använd vinkelparenteser för att fånga ett värde från URL:en.

- Fångade värden kan eventuellt innehålla en konverteringstyp. Använd t.ex. `<int:name>` för att fånga en heltalsparameter. Om en omvandlare inte ingår matchas alla strängar, exklusive tecknet `/`.

- Det finns inget behov av att lägga till ett inledande snedstreck, eftersom alla webbadresser har det. Till exempel är det `artiklar`, inte `/artiklar`.

Exempel på förfrågningar:

- En förfrågan till `/articles/2005/03/` skulle matcha den tredje posten i listan. Django skulle anropa funktionen `views.month_archive(request, year=2005, month=3)`.

- `/articles/2003/` skulle matcha det första mönstret i listan, inte det andra, eftersom mönstren testas i ordning och det första är det första testet som ska godkännas. Känn dig fri att utnyttja beställningen för att infoga specialfall som detta. Här skulle Django anropa funktionen `views.special_case_2003(request)`

- `/articles/2003` skulle inte matcha något av dessa mönster, eftersom varje mönster kräver att URL:en slutar med ett snedstreck.

- `/articles/2003/03/building-a-django-site/` skulle matcha det slutliga mönstret. Django skulle anropa funktionen `views.article_detail(request, year=2003, month=3, slug="building-a-django-site")`.

## Banomvandlare

Följande sökvägskonverterare är tillgängliga som standard:

- `str` - Matchar alla icke-tomma strängar, exklusive sökvägsseparatorn `'/'`. Detta är standardvärdet om en konverterare inte ingår i uttrycket.

- `int` - Motsvarar noll eller ett positivt heltal. Returnerar ett `int`.

- `slug` - Matchar alla slug-strängar som består av ASCII-bokstäver eller siffror, plus bindestreck och understreck. Till exempel `bygg-din-1:a-django-sida`.

- `uuid` - Matchar ett formaterat UUID. För att förhindra att flera webbadresser mappas till samma sida måste bindestreck inkluderas och bokstäver måste vara gemener. Till exempel `075194d3-6885-417e-a8a8-6c931e272f00`. Returnerar en `UUID`-instans.

- `path` - Matchar alla icke-tomma strängar, inklusive sökvägsseparatorn `'/'`. Detta gör att du kan matcha mot en komplett URL-sökväg snarare än ett segment av en URL-sökväg som med `str`.

## Registrering av anpassade sökvägsomvandlare

För mer komplexa matchningskrav kan du definiera dina egna banomvandlare.

En converter är en klass som innehåller följande:

- Ett `regex`-klassattribut, som en sträng.

- En `to_python(self, value)`-metod, som hanterar konvertering av den matchade strängen till den typ som ska skickas till vyfunktionen. Den bör ge upphov till `ValueError` om den inte kan konvertera det givna värdet. Ett `ValueError` tolkas som ingen matchning och som en konsekvens av detta skickas ett 404-svar till användaren om inte ett annat URL-mönster matchar.

- En `to_url(self, value)`-metod, som hanterar konvertering av Python-typen till en sträng som ska användas i URL:en. Den bör ge upphov till `ValueError` om den inte kan konvertera det givna värdet. Ett `ValueError` tolkas som ingen matchning och som en konsekvens av detta kommer `reverse()` att ge `NoReverseMatch` om inte ett annat URL-mönster matchar.

Till exempel:

    class FourDigitYearConverter:
        regex = "[0-9]{4}"

        def to_python(self, value):
            return int(value)

        def to_url(self, value):
            return "%04d" % value

Registrera anpassade omvandlarklasser i din URLconf med `register_converter()`:

    from django.urls import path, register_converter

    from . import converters, views

    register_converter(converters.FourDigitYearConverter, "yyyy")

    urlpatterns = [
        path("articles/2003/", views.special_case_2003),
        path("articles/<yyyy:year>/", views.year_archive),
        ...,
    ]

## Använda reguljära uttryck

Om syntaxen för sökvägar och omvandlare inte är tillräcklig för att definiera dina URL-mönster kan du också använda reguljära uttryck. För att göra det, använd `re_path()` istället för `path()`.

I Python är syntaxen för namngivna grupper av reguljära uttryck `(?P<name>pattern)`, där `name` är namnet på gruppen och `pattern` är ett mönster som ska matchas.

Här är exemplet URLconf från tidigare, omskrivet med hjälp av reguljära uttryck:

    from django.urls import path, re_path

    from . import views

    urlpatterns = [
        path("articles/2003/", views.special_case_2003),
        re_path(r"^articles/(?P<year>[0-9]{4})/$", views.year_archive),
        re_path(r"^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$", views.month_archive),
        re_path(
            r"^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$",
            views.article_detail,
        ),
    ]

Detta åstadkommer ungefär samma sak som det föregående exemplet, förutom:

- De exakta webbadresser som kommer att matcha är något mer begränsade. Till exempel kommer årtalet 10000 inte längre att matcha eftersom årtalen måste vara exakt fyra siffror långa.

- Varje argument som fångas upp skickas till vyn som en sträng, oavsett vilken typ av matchning det reguljära uttrycket ger.

När du byter från att använda `path()` till `re_path()` eller vice versa är det särskilt viktigt att vara medveten om att typen av vyargument kan ändras och att du därför kan behöva anpassa dina vyer.

### Använda icke namngivna grupper av reguljära uttryck

Förutom syntaxen för namngivna grupper, t.ex. `(?P<year>[0-9]{4})`, kan du också använda den kortare syntaxen för icke namngivna grupper, t.ex. `([0-9]{4})`.

Denna användning är inte särskilt rekommenderad eftersom det gör det lättare att av misstag införa fel mellan den avsedda betydelsen av en match och argumenten i vyn.

I båda fallen rekommenderas att endast en stil används inom en given regex. När båda stilarna blandas ignoreras alla icke namngivna grupper och endast namngivna grupper skickas till view-funktionen.

### Nästlade argument

Reguljära uttryck tillåter nästlade argument, och Django kommer att lösa dem och skicka dem till vyn. Vid reversering kommer Django att försöka fylla i alla yttre infångade argument och ignorera alla nästlade infångade argument. Tänk på följande URL-mönster som valfritt tar ett sidargument:

    from django.urls import re_path

    urlpatterns = [
        re_path(r"^blog/(page-([0-9]+)/)?$", blog_articles),  # bad
        re_path(r"^comments/(?:page-(?P<page_number>[0-9]+)/)?$", comments),  # good
    ]

Båda mönstren använder nästlade argument och kommer att lösas: till exempel kommer `blog/page-2/` att resultera i en matchning till `blog_articles` med två positionella argument: `page-2/` och `2`. Det andra mönstret för `comments` kommer att matcha `comments/page-2/` med nyckelordsargumentet `page_number` satt till 2. Det yttre argumentet i detta fall är ett icke-fångande argument `(?:...)`.

Vyn `blog_articles` behöver det yttersta infångade argumentet för att kunna vändas, `page-2/` eller inga argument i det här fallet, medan `comments` kan vändas med antingen inga argument eller ett värde för `page_number`.

Kapslade argument skapar en stark koppling mellan vyargumenten och URL:en, vilket illustreras av `blog_articles`: vyn tar emot en del av URL:en (`page-2/`) i stället för bara det värde som vyn är intresserad av. Denna koppling är ännu mer uttalad vid reversering, eftersom vi för att reversera vyn måste skicka URL-biten istället för sidnumret.

En tumregel är att bara fånga de värden som vyn behöver arbeta med och att använda argument som inte fångas när det reguljära uttrycket behöver ett argument men vyn ignorerar det.

## Vad URLconf söker efter

URLconf söker mot den begärda URL:en som en vanlig Python-sträng. Detta inkluderar inte GET- eller POST-parametrar eller domännamnet.

Till exempel, i en begäran till `https://www.example.com/myapp/` kommer URLconf att leta efter `myapp/`.

I en begäran till `https://www.example.com/myapp/?page=3` kommer URLconf att leta efter `myapp/`.

URLconf tittar inte på förfrågningsmetoden. Med andra ord kommer alla förfrågningsmetoder - `POST`, `GET`, `HEAD` osv. – kommer att dirigeras till samma funktion för samma URL.

## Ange standardvärden för vyargument

Ett praktiskt trick är att ange standardparametrar för dina vyers argument. Här är ett exempel på URLconf och view:

    # URLconf
    from django.urls import path

    from . import views

    urlpatterns = [
        path("blog/", views.page),
        path("blog/page<int:num>/", views.page),
    ]

    # View (in blog/views.py)
    def page(request, num=1):
        # Output the appropriate page of blog entries, according to num.
        ...

I exemplet ovan pekar båda URL-mönstren på samma vy - `views.page` - men det första mönstret fångar inte upp något från URL:en. Om det första mönstret matchar kommer funktionen `page()` att använda sitt standardargument för `num`, `1`. Om det andra mönstret matchar, kommer `page()` att använda det värde för `num` som fångades upp.

## Prestanda

Django bearbetar reguljära uttryck i listan `urlpatterns` som sammanställs första gången den öppnas. Efterföljande förfrågningar använder den cachade konfigurationen via URL-resolvern.

## Syntax för variabeln ”Urlpatterns

`urlpatterns` bör vara en sequence av `path()` och/eller `re_path()` instanser.

## Felhantering

När Django inte kan hitta en matchning för den begärda URL:en, eller när ett undantag uppstår, anropar Django en vy för felhantering.

De vyer som ska användas i dessa fall specificeras av fyra variabler. Deras standardvärden bör räcka för de flesta projekt, men ytterligare anpassning är möjlig genom att åsidosätta deras standardvärden.

Se dokumentationen om Anpassa felvyer för fullständig information.

Sådana värden kan ställas in i din rot-URLconf. Att ställa in dessa variabler i någon annan URLconf kommer inte att ha någon effekt.

Värdena måste vara callables, eller strängar som representerar den fullständiga Python-importvägen till den vy som ska anropas för att hantera det aktuella feltillståndet.

Variablerna är:

- `handler400` – Se `django.conf.urls.handler400`.

- `handler403` – Se `django.conf.urls.handler403`.

- `handler404` – Se `django.conf.urls.handler404`.

- `handler500` – Se `django.conf.urls.handler500`.

## Inkludera andra URLconfs

När som helst kan dina ”URL-mönster” ”inkludera” andra URLconf-moduler. Detta innebär i princip att en uppsättning webbadresser ”rotas” under andra.

Här är till exempel ett utdrag ur URLconf för själva Django-webbplatsen. Den innehåller ett antal andra URLconfs:

    from django.urls import include, path

    urlpatterns = [
        # ... snip ...
        path("community/", include("aggregator.urls")),
        path("contact/", include("contact.urls")),
        # ... snip ...
    ]

Whenever Django encounters `include()`, it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.

En annan möjlighet är att inkludera ytterligare URL-mönster genom att använda en lista med `path()`-instanser. Tänk till exempel på denna URLconf:

    from django.urls import include, path

    from apps.main import views as main_views
    from credit import views as credit_views

    extra_patterns = [
        path("reports/", credit_views.report),
        path("reports/<int:id>/", credit_views.report),
        path("charge/", credit_views.charge),
    ]

    urlpatterns = [
        path("", main_views.homepage),
        path("help/", include("apps.help.urls")),
        path("credit/", include(extra_patterns)),
    ]

I det här exemplet kommer webbadressen `/credit/reports/` att hanteras av Django-vyn `credit_views.report()`.

Detta kan användas för att ta bort redundans från URLconfs där ett enda mönsterprefix används upprepade gånger. Tänk till exempel på detta URLconf:

    from django.urls import path
    from . import views

    urlpatterns = [
        path("<page_slug>-<page_id>/history/", views.history),
        path("<page_slug>-<page_id>/edit/", views.edit),
        path("<page_slug>-<page_id>/discuss/", views.discuss),
        path("<page_slug>-<page_id>/permissions/", views.permissions),
    ]

Vi kan förbättra detta genom att bara ange det gemensamma sökvägsprefixet en gång och gruppera de suffix som skiljer sig åt:

    from django.urls import include, path
    from . import views

    urlpatterns = [
        path(
            "<page_slug>-<page_id>/",
            include(
                [
                    path("history/", views.history),
                    path("edit/", views.edit),
                    path("discuss/", views.discuss),
                    path("permissions/", views.permissions),
                ]
            ),
        ),
    ]

### Uppfångade parametrar

En inkluderad URLconf tar emot eventuella parametrar från överordnade URLconfs, så följande exempel är giltigt:

    # In settings/urls/main.py
    from django.urls import include, path

    urlpatterns = [
        path("<username>/blog/", include("foo.urls.blog")),
    ]

    # In foo/urls/blog.py
    from django.urls import path
    from . import views

    urlpatterns = [
        path("", views.blog.index),
        path("archive/", views.blog.archive),
    ]

I exemplet ovan skickas den fångade variabeln `"username"` till den inkluderade URLconf, som förväntat.

## Överföra extra alternativ till vyfunktioner

URLconfs har en hook som gör att du kan skicka extra argument till dina vyfunktioner, som en Python-ordbok.

Funktionen `path()` kan ta ett valfritt tredje argument som bör vara en ordbok med extra nyckelordsargument som ska skickas till vyfunktionen.

Till exempel:

    from django.urls import path
    from . import views

    urlpatterns = [
        path("blog/<int:year>/", views.year_archive, {"foo": "bar"}),
    ]

I det här exemplet kommer Django att anropa `views.year_archive(request, year=2005, foo='bar')` för en begäran till `/blog/2005/`.

Denna teknik används i syndication framework för att skicka metadata och alternativ till vyer.

Hantering av konflikter

Det är möjligt att ha ett URL-mönster som fångar upp namngivna nyckelordsargument och även skickar argument med samma namn i sin ordbok med extra argument. När detta händer kommer argumenten i ordlistan att användas i stället för de argument som fångas upp i URL:en.

### Skicka extra alternativ till `include()`

På samma sätt kan du skicka extra alternativ till `include()` och varje rad i den inkluderade URLconf kommer att skickas till de extra alternativen.

Till exempel är dessa två URLconf-uppsättningar funktionellt identiska:

Set ett:

    # main.py
    from django.urls import include, path

    urlpatterns = [
        path("blog/", include("inner"), {"blog_id": 3}),
    ]

    # inner.py
    from django.urls import path
    from mysite import views

    urlpatterns = [
        path("archive/", views.archive),
        path("about/", views.about),
    ]

Set två:

    # main.py
    from django.urls import include, path
    from mysite import views

    urlpatterns = [
        path("blog/", include("inner")),
    ]

    # inner.py
    from django.urls import path

    urlpatterns = [
        path("archive/", views.archive, {"blog_id": 3}),
        path("about/", views.about, {"blog_id": 3}),
    ]

Observera att extra alternativ alltid kommer att skickas till alla rader i den inkluderade URLconf, oavsett om radens vy faktiskt accepterar dessa alternativ som giltiga. Av denna anledning är denna teknik endast användbar om du är säker på att varje vy i den inkluderade URLconf accepterar de extra alternativ du skickar.

## Omvänd upplösning av webbadresser

Ett vanligt behov när man arbetar med ett Django-projekt är möjligheten att få webbadresser i sina slutliga former antingen för inbäddning i genererat innehåll (vyer och tillgångars webbadresser, webbadresser som visas för användaren etc.) eller för hantering av navigeringsflödet på serversidan (omdirigeringar etc.)

It is strongly desirable to avoid hardcoding these URLs (a laborious, non-scalable and error-prone strategy). Equally dangerous is devising ad-hoc mechanisms to generate URLs that are parallel to the design described by the URLconf, which can result in the production of URLs that become stale over time.

Vad som behövs är med andra ord en DRY-mekanism. Bland andra fördelar skulle det göra det möjligt att utveckla URL-designen utan att behöva gå igenom hela projektets källkod för att söka efter och ersätta föråldrade URL:er.

Den primära information vi har tillgänglig för att få en URL är en identifiering (t.ex. namnet) av den vy som ansvarar för att hantera den. Andra delar av informationen som nödvändigtvis måste delta i sökningen efter rätt URL är typerna (positionella, nyckelord) och värdena för vyargumenten.

Django tillhandahåller en lösning så att URL-mapparen är den enda förvararen av URL-designen. Du matar den med din URLconf och sedan kan den användas i båda riktningarna:

- Med utgångspunkt i en URL som begärs av användaren/webbläsaren anropar den rätt Django-vy och ger alla argument som den kan behöva med deras värden som extraheras från URL.

- Med utgångspunkt från identifieringen av motsvarande Django-vy plus värdena för de argument som skulle skickas till den, får du den tillhörande URL:en.

Den första är den användning som vi har diskuterat i de tidigare avsnitten. Den andra är vad som kallas omvänd upplösning av webbadresser, omvänd URL-matchning, omvänd URL-uppslagning eller helt enkelt URL-reversering.

Django tillhandahåller verktyg för att utföra URL-reversering som matchar de olika lager där webbadresser behövs:

- I mallar: Använda malltaggen `url`.

- I Python-kod: Med hjälp av funktionen `reverse()`.

- I kod på högre nivå relaterad till hantering av webbadresser för Django-modellinstanser: Metoden `get_absolute_url()`.

### Exempel

Tänk igen på denna URLconf-post:

    from django.urls import path

    from . import views

    urlpatterns = [
        # ...
        path("articles/<int:year>/", views.year_archive, name="news-year-archive"),
        # ...
    ]

Enligt denna design är URL:en för arkivet som motsvarar år nnnn `/artiklar/<nnnn>/`.

Du kan få dessa i mallkod genom att använda:

    <a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
    {# Or with the year in a template context variable: #}
    <ul>
    {% for yearvar in year_list %}
    <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
    {% endfor %}
    </ul>

Eller i Python-kod:

    from django.http import HttpResponseRedirect
    from django.urls import reverse

    def redirect_to_year(request):
        # ...
        year = 2006
        # ...
        return HttpResponseRedirect(reverse("news-year-archive", args=(year,)))

Om det av någon anledning skulle beslutas att URL:erna där innehållet i de årliga artikelarkiven publiceras ska ändras, behöver du bara ändra posten i URLconf.

I vissa scenarier där vyerna är av generisk karaktär kan det finnas ett många-till-ett-förhållande mellan webbadresser och vyer. I dessa fall är vynamnet inte en tillräckligt bra identifierare för det när det är dags att vända webbadresser. Läs nästa avsnitt för att få veta mer om den lösning som Django tillhandahåller för detta.

## Namngivning av URL-mönster

För att kunna utföra URL-reversering måste du använda namngivna URL-mönster som i exemplen ovan. Strängen som används för URL-namnet kan innehålla vilka tecken du vill. Du är inte begränsad till giltiga Python-namn.

When naming URL patterns, choose names that are unlikely to clash with other applications’ choice of names. If you call your URL pattern `comment` and another application does the same thing, the URL that `reverse()` finds depends on whichever pattern is last in your project’s `urlpatterns` list.

Om du sätter ett prefix på dina URL-namn, kanske härlett från applikationens namn (t.ex. `myapp-comment` i stället för `comment`), minskar risken för kollisioner.

You can deliberately choose the same URL name as another application if you want to override a view. For example, a common use case is to override the `LoginView`. Parts of Django and most third-party apps assume that this view has a URL pattern with the name `login`. If you have a custom login view and give its URL the name `login`, `reverse()` will find your custom view as long as it’s in `urlpatterns` after `django.contrib.auth.urls` is included (if that’s included at all).

You may also use the same name for multiple URL patterns if they differ in their arguments. In addition to the URL name, `reverse()` matches the number of arguments and the names of the keyword arguments. Path converters can also raise `ValueError` to indicate no match, see Registrering av anpassade sökvägsomvandlare for details.

## Namnrymder för URL

### Introduktion

Med URL-namnrymder kan du unikt vända namngivna URL-mönster även om olika program använder samma URL-namn. Det är en god praxis för tredjepartsappar att alltid använda namnrymder för webbadresser (som vi gjorde i handledningen). På samma sätt kan du också vända webbadresser om flera instanser av en applikation distribueras. Med andra ord, eftersom flera instanser av en enda applikation kommer att dela namngivna webbadresser, ger namnrymder ett sätt att skilja dessa namngivna webbadresser åt.

Django applications that make proper use of URL namespacing can be deployed more than once for a particular site. For example `django.contrib.admin` has an `AdminSite` class which allows you to deploy more than one instance of the admin. In a later example, we’ll discuss the idea of deploying the polls application from the tutorial in two different locations so we can serve the same functionality to two different audiences (authors and publishers).

En URL-namnrymd består av två delar, som båda är strängar:

applikationens namnområde

  Detta beskriver namnet på den applikation som distribueras. Varje instans av en enskild applikation kommer att ha samma applikationsnamnrymd. Till exempel har Djangos admin-applikation det något förutsägbara applikationsnamnområdet `'admin'`.

namnrymd för instans

  Detta identifierar en specifik instans av en applikation. Instansnamnrymder bör vara unika för hela projektet. En instansnamnrymd kan dock vara densamma som applikationens namnrymd. Detta används för att ange en standardinstans av en applikation. Till exempel har standardinstansen Django admin ett instansnamnområde på `'admin'`.

Namngivna URL:er anges med operatorn `':'`. Huvudindexsidan för admin-programmet refereras till exempel med `'admin:index'`. Detta anger namnrymden `'admin'` och den namngivna URL:en `'index'`.

Namnrymder kan också vara nästlade. Den namngivna URL:en `'sports:polls:index'` letar efter ett mönster med namnet `'index'` i namnrymden `'polls'` som i sin tur definieras i namnrymden `'sports'` på högsta nivån.

### Återställning av namnlösa URL:er

När Django får en URL med namnområde (t.ex. `'polls:index'`) att lösa, delar Django upp det fullständigt kvalificerade namnet i delar och försöker sedan följande uppslagning:

1. Först letar Django efter en matchande applikationsnamnrymd (i det här exemplet `'polls'`). Detta kommer att ge en lista över instanser av den applikationen.

2. If there is a current application defined, Django finds and returns the URL resolver for that instance. The current application can be specified with the `current_app` argument to the `reverse()` function.

   Malltaggen `url` använder namnrymden för den aktuella vyn som aktuell applikation i en `RequestContext`. Du kan åsidosätta denna standard genom att ställa in den aktuella applikationen på attributet `request.current_app`.

3. Om det inte finns någon aktuell applikation letar Django efter en standardapplikationsinstans. Standardapplikationsinstansen är den instans som har en instance namespace som matchar application namespace (i det här exemplet en instans av `polls` som heter `'polls'`).

4. Om det inte finns någon standardapplikationsinstans kommer Django att välja den senast distribuerade instansen av applikationen, oavsett vad dess instansnamn kan vara.

5. Om den angivna namnrymden inte matchar en applikationsnamnrymd i steg 1, kommer Django att försöka göra en direktuppslagning av namnrymden som en instansnamnrymd.

Om det finns nästlade namnrymder upprepas dessa steg för varje del av namnrymden tills endast vynamnet är olöst. Vynamnet kommer då att lösas upp till en URL i den namnrymd som har hittats.

#### Exempel

För att visa hur den här lösningsstrategin fungerar kan vi ta ett exempel med två instanser av applikationen `polls` från handledningen: en som heter `'author-polls` och en som heter `'publisher-polls`. Antag att vi har förbättrat applikationen så att den tar hänsyn till instansnamnrymden när den skapar och visar omröstningar.

`urls.py`

    from django.urls import include, path

    urlpatterns = [
        path("author-polls/", include("polls.urls", namespace="author-polls")),
        path("publisher-polls/", include("polls.urls", namespace="publisher-polls")),
    ]

`polls/urls.py`

    from django.urls import path

    from . import views

    app_name = "polls"
    urlpatterns = [
        path("", views.IndexView.as_view(), name="index"),
        path("<int:pk>/", views.DetailView.as_view(), name="detail"),
        ...,
    ]

Med hjälp av denna inställning kan följande sökningar göras:

- Om en av instanserna är aktuell - säg, om vi renderade detaljsidan i instansen `'author-polls` - kommer `'polls:index` att lösa till indexsidan i instansen `'author-polls`; dvs. båda följande kommer att resultera i `"/author-polls/"`.

  I metoden för en klassbaserad syn:

      reverse("polls:index", current_app=self.request.resolver_match.namespace)

  och i mallen:

      {% url 'polls:index' %}

- Om det inte finns någon aktuell instans - till exempel om vi renderar en sida någon annanstans på webbplatsen - kommer `'polls:index'` att lösas till den senast registrerade instansen av `polls`. Eftersom det inte finns någon standardinstans (instansnamnrymden för `'polls`), kommer den senast registrerade instansen av `polls` att användas. Detta skulle vara `'publisher-polls` eftersom den deklareras sist i `urlpatterns`.

- `'author-polls:index'` will always resolve to the index page of the instance `'author-polls'` (and likewise for `'publisher-polls'`).

Om det också fanns en standardinstans - dvs. en instans med namnet `'polls'` - skulle den enda förändringen jämfört med ovan vara i det fall då det inte finns någon aktuell instans (den andra punkten i listan ovan). I det här fallet skulle `'polls:index'` resolva till indexsidan för standardinstansen istället för den instans som deklarerades sist i `urlpatterns`.

### URL-namnrymder och inkluderade URL-konf

Applikationsnamnrymder för inkluderade URLconfs kan anges på två sätt.

För det första kan du ange ett `app_name`-attribut i den inkluderade URLconf-modulen, på samma nivå som `urlpatterns`-attributet. Du måste skicka den faktiska modulen, eller en strängreferens till modulen, till `include()`, inte själva listan med `urlpatterns`.

`polls/urls.py`

    from django.urls import path

    from . import views

    app_name = "polls"
    urlpatterns = [
        path("", views.IndexView.as_view(), name="index"),
        path("<int:pk>/", views.DetailView.as_view(), name="detail"),
        ...,
    ]

`urls.py`

    from django.urls import include, path

    urlpatterns = [
        path("polls/", include("polls.urls")),
    ]

De webbadresser som definieras i `polls.urls` kommer att ha en applikationsnamnrymd `polls`.

För det andra kan du inkludera ett objekt som innehåller inbäddade namnrymdsdata. Om du `include()` en lista med `path()` eller `re_path()` instanser, kommer URL:erna som finns i det objektet att läggas till i det globala namnområdet. Men du kan också `include()` en 2-tupel som innehåller:

    (<list of path()/re_path() instances>, <application namespace>)

Till exempel:

    from django.urls import include, path

    from . import views

    polls_patterns = (
        [
            path("", views.IndexView.as_view(), name="index"),
            path("<int:pk>/", views.DetailView.as_view(), name="detail"),
        ],
        "polls",
    )

    urlpatterns = [
        path("polls/", include(polls_patterns)),
    ]

Detta kommer att inkludera de nominerade URL-mönstren i den angivna applikationens namnrymd.

Instansens namnområde kan anges med argumentet `namespace` till `include()`. Om instansnamnområdet inte anges kommer det att vara standard för det inkluderade URLconfs applikationsnamnområde. Detta innebär att det också kommer att vara standardinstansen för det namnområdet.