# Django 6.0.5 documentation

# Middleware

Middleware är ett ramverk av hooks i Djangos request/response-behandling. Det är ett lätt ”plugin”-system på låg nivå för att globalt ändra Djangos in- eller utdata.

Varje middleware-komponent är ansvarig för att utföra en specifik funktion. Till exempel innehåller Django en middleware-komponent, `AuthenticationMiddleware`, som associerar användare med förfrågningar med hjälp av sessioner.

Detta dokument förklarar hur middleware fungerar, hur du aktiverar middleware och hur du skriver din egen middleware. Django levereras med några inbyggda middleware som du kan använda direkt ur lådan. De är dokumenterade i inbyggd middleware-referens.

## Skriva din egen middleware

En middleware-fabrik är en callable som tar en `get_response` callable och returnerar en middleware. En middleware är en anropsbar som tar emot en begäran och returnerar ett svar, precis som en vy.

En middleware kan skrivas som en funktion som ser ut så här:

    def simple_middleware(get_response):
        # One-time configuration and initialization.

        def middleware(request):
            # Code to be executed for each request before
            # the view (and later middleware) are called.

            response = get_response(request)

            # Code to be executed for each request/response after
            # the view is called.

            return response

        return middleware

Eller så kan det skrivas som en klass vars instanser är anropsbara, så här:

    class SimpleMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
            # One-time configuration and initialization.

        def __call__(self, request):
            # Code to be executed for each request before
            # the view (and later middleware) are called.

            response = self.get_response(request)

            # Code to be executed for each request/response after
            # the view is called.

            return response

Den `get_response` callable som tillhandahålls av Django kan vara den faktiska vyn (om detta är den sista listade middleware) eller det kan vara nästa middleware i kedjan. Den aktuella mellanvaran behöver inte veta eller bry sig om exakt vad den är, bara att den representerar vad som kommer härnäst.

Ovanstående är en liten förenkling - den anropbara `get_response` för den sista middlewaren i kedjan kommer inte att vara den faktiska vyn utan snarare en omslagsmetod från hanteraren som tar hand om att tillämpa view middleware, anropa vyn med lämpliga URL-argument och tillämpa template-response och exception middleware.

Middleware kan antingen stödja endast synkrona Python (standard), endast asynkrona Python, eller båda. Se Asynkront stöd för detaljer om hur man annonserar vad man stödjer, och vet vilken typ av förfrågan man får.

Middleware kan finnas var som helst på din Python-väg.

### `__init__(get_response)`

Middleware-fabriker måste acceptera ett `get_response`-argument. Du kan också initiera ett globalt tillstånd för mellanvaran. Tänk på ett par försiktighetsåtgärder:

- Django initierar din middleware med endast `get_response` argumentet, så du kan inte definiera `__init__()` som kräver några andra argument.

- Till skillnad från metoden `__call__()` som anropas en gång per förfrågan, anropas `__init__()` bara en gång, när webbservern startar.

### Markera middleware som oanvänd

Det är ibland användbart att vid uppstart avgöra om en del av middleware ska användas. I dessa fall kan din middlewares `__init__()` metod ge upphov till `MiddlewareNotUsed`. Django kommer då att ta bort den middleware från middleware-processen och logga ett debug-meddelande till loggern django.begäran när `DEBUG` är `True`.

## Aktivering av middleware

För att aktivera en middleware-komponent lägger du till den i listan `MIDDLEWARE` i dina Django-inställningar.

I `MIDDLEWARE` representeras varje middleware-komponent av en sträng: den fullständiga Python-sökvägen till middleware-fabrikens klass- eller funktionsnamn. Här är till exempel standardvärdet som skapades av `django-admin startproject`:

    MIDDLEWARE = [
        "django.middleware.security.SecurityMiddleware",
        "django.contrib.sessions.middleware.SessionMiddleware",
        "django.middleware.common.CommonMiddleware",
        "django.middleware.csrf.CsrfViewMiddleware",
        "django.contrib.auth.middleware.AuthenticationMiddleware",
        "django.contrib.messages.middleware.MessageMiddleware",
        "django.middleware.clickjacking.XFrameOptionsMiddleware",
    ]

En Django-installation kräver inte någon middleware - `MIDDLEWARE` kan vara tom om du vill - men det rekommenderas starkt att du åtminstone använder `CommonMiddleware`.

Ordningen i `MIDDLEWARE` är viktig eftersom ett mellanprogram kan vara beroende av andra mellanprogram. Till exempel lagrar `AuthenticationMiddleware` den autentiserade användaren i sessionen; därför måste den köras efter `SessionMiddleware`. Se Beställning av mellanprogramvara för några vanliga tips om ordning av Django middleware-klasser.

## Ordning och skiktning av mellanprogram

Under förfrågningsfasen, innan vyn anropas, tillämpar Django middleware i den ordning som definieras i `MIDDLEWARE`, uppifrån och ner.

Du kan tänka på det som en lök: varje middleware-klass är ett ”lager” som omsluter vyn, som finns i lökens kärna. Om begäran passerar genom alla lager i löken (varje lager anropar `get_response` för att skicka begäran till nästa lager), hela vägen till vyn i kärnan, kommer svaret sedan att passera genom varje lager (i omvänd ordning) på väg tillbaka ut.

Om ett av lagren bestämmer sig för att kortsluta och returnera ett svar utan att någonsin anropa sitt `get_response`, kommer inget av lagren i löken inuti det lagret (inklusive vyn) att se begäran eller svaret. Svaret kommer bara att returneras genom samma lager som begäran passerade in genom.

## Andra middleware-hooks

Förutom det grundläggande request/response-mönstret för middleware som beskrivits tidigare kan du lägga till tre andra specialmetoder till klassbaserade middleware:

### `process_view()`

process_view(request, view_func, view_args, view_kwargs)

`request` är ett `HttpRequest` objekt. `view_func` är den Python-funktion som Django ska använda. (Det är det faktiska funktionsobjektet, inte namnet på funktionen som en sträng.) `view_args` är en lista över positionella argument som kommer att skickas till vyn, och `view_kwargs` är en ordbok över nyckelordsargument som kommer att skickas till vyn. Varken `view_args` eller `view_kwargs` inkluderar det första vyargumentet (`request`).

`process_view()` anropas precis innan Django anropar vyn.

Det bör returnera antingen `None` eller ett `HttpResponse`-objekt. Om det returnerar `None` kommer Django att fortsätta bearbeta denna begäran, köra alla andra `process_view()` middleware och sedan den lämpliga vyn. Om det returnerar ett `HttpResponse`-objekt kommer Django inte att bry sig om att anropa lämplig vy; det kommer att tillämpa svarsmellanprogram till det `HttpResponse` och returnera resultatet.

Observera

Åtkomst till `request.POST` inuti middleware innan vyn körs eller i `process_view()` kommer att förhindra att en vy som körs efter middleware kan modifiera uppladdningshanterarna för begäran, och bör normalt undvikas.

Klassen `CsrfViewMiddleware` kan betraktas som ett undantag, eftersom den tillhandahåller dekoratorerna `csrf_exempt()` och `csrf_protect()` som gör det möjligt för vyer att uttryckligen styra vid vilken tidpunkt CSRF-valideringen ska ske.

### `process_exception()`

process_exception(request, exception)

`request` är ett `HttpRequest` objekt. `exception` är ett `Exception` objekt som tas upp av view funktionen.

Django anropar `process_exception()` när en vy ger upphov till ett undantag. `process_exception()` bör returnera antingen `None` eller ett `HttpResponse`-objekt. Om den returnerar ett `HttpResponse`-objekt kommer mallsvaret och svarsmellanvaran att tillämpas och det resulterande svaret returneras till webbläsaren. Annars börjar standardhantering av undantag gälla.

Återigen körs middleware i omvänd ordning under svarsfasen, som inkluderar `process_exception`. Om en undantagsmellanvara returnerar ett svar, kommer `process_exception`-metoderna i mellanvaruklasserna ovanför den mellanvaran inte att anropas alls.

### `process_template_response()`

process_template_response(request, response)

`request` är ett `HttpRequest`-objekt. `response` är `TemplateResponse`-objektet (eller motsvarande) som returneras av en Django-vy eller av en middleware.

`process_template_response()` anropas strax efter att vyn har körts färdigt, om svarsinstansen har en `render()`-metod, vilket indikerar att det är en `TemplateResponse` eller motsvarande.

Den måste returnera ett svarsobjekt som implementerar en `render`-metod. Det kan ändra det givna `respons` genom att ändra `response.template_name` och `response.context_data`, eller så kan det skapa och returnera en helt ny `TemplateResponse` eller motsvarande.

Du behöver inte uttryckligen rendera svaren - svaren renderas automatiskt när alla middleware för mallsvar har anropats.

Middleware körs i omvänd ordning under svarsfasen, som inkluderar `process_template_response()`.

## Hantering av strömmande svar

Till skillnad från `HttpResponse` har `StreamingHttpResponse` inte attributet `content`. Som ett resultat kan middleware inte längre anta att alla svar kommer att ha ett `content`-attribut. Om de behöver tillgång till innehållet måste de testa för strömmande svar och justera sitt beteende i enlighet därmed:

    if response.streaming:
        response.streaming_content = wrap_streaming_content(response.streaming_content)
    else:
        response.content = alter_content(response.content)

Observera

`streaming_content` bör antas vara för stort för att kunna hållas i minnet. Response middleware kan omsluta det i en ny generator, men får inte konsumera det. Omslag implementeras typiskt på följande sätt:

    def wrap_streaming_content(content):
        for chunk in content:
            yield alter_content(chunk)

`StreamingHttpResponse` tillåter både synkrona och asynkrona iteratorer. Inkapslingsfunktionen måste matcha. Kontrollera `StreamingHttpResponse.is_async` om din mellanvara behöver stödja båda typerna av iteratorer.

## Hantering av undantag

Django konverterar automatiskt undantag som tas upp av vyn eller av middleware till ett lämpligt HTTP-svar med en felstatuskod. Vissa undantag konverteras till 4xx-statuskoder, medan ett okänt undantag konverteras till en 500-statuskod.

Denna konvertering sker före och efter varje middleware (du kan tänka på det som den tunna filmen mellan varje lager av löken), så att varje middleware alltid kan lita på att få någon form av HTTP-svar tillbaka från anropet till dess `get_response` callable. Middleware behöver inte oroa sig för att linda in sitt anrop till `get_response` i en `try/except` och hantera ett undantag som kan ha uppstått av en senare middleware eller vyn. Även om nästa middleware i kedjan till exempel ger upphov till ett `Http404`-undantag, kommer din middleware inte att se det undantaget; istället får den ett `HttpResponse`-objekt med en `status_code` på 404.

Du kan sätta `DEBUG_PROPAGATE_EXCEPTIONS` till `True` för att hoppa över denna konvertering och sprida undantag uppåt.

## Asynkront stöd

Middleware kan stödja alla kombinationer av synkrona och asynkrona förfrågningar. Django kommer att anpassa förfrågningar för att passa mellanvarans krav om det inte kan stödja båda, men med en prestandaförlust.

Som standard antar Django att din middleware endast kan hantera synkrona förfrågningar. För att ändra dessa antaganden, ställ in följande attribut på din middleware fabriksfunktion eller klass:

- `sync_capable` är en boolean som anger om mellanvaran kan hantera synkrona förfrågningar. Standardvärdet är `True`.

- `async_capable` är en boolean som anger om mellanvaran kan hantera asynkrona förfrågningar. Standardvärdet är `False`.

Om din middleware har både `sync_capable = True` och `async_capable = True`, kommer Django att skicka begäran utan att konvertera den. I det här fallet kan du räkna ut om din mellanvara kommer att ta emot asynkrona förfrågningar genom att kontrollera om `get_response`-objektet du skickas är en coroutine-funktion, med hjälp av `asgiref.sync.iscoroutinefunction`.

Modulen `django.utils.decorators` innehåller `sync_only_middleware()`, `async_only_middleware()`, och `sync_and_async_middleware()` decorators som låter dig tillämpa dessa flaggor på middleware-fabriksfunktioner.

Den returnerade callable måste matcha sync- eller async-karaktären hos `get_response`-metoden. Om du har en asynkron `get_response` måste du returnera en coroutine-funktion (`async def`).

metoderna `process_view`, `process_template_response` och `process_exception`, om de tillhandahålls, bör också anpassas för att matcha sync/async-läget. Django kommer dock att anpassa dem individuellt efter behov om du inte gör det, med en extra prestandaförlust.

Här är ett exempel på hur man skapar en middleware-funktion som stöder båda:

    from asgiref.sync import iscoroutinefunction
    from django.utils.decorators import sync_and_async_middleware

    @sync_and_async_middleware
    def simple_middleware(get_response):
        # One-time configuration and initialization goes here.
        if iscoroutinefunction(get_response):

            async def middleware(request):
                # Do something here!
                response = await get_response(request)
                return response

        else:

            def middleware(request):
                # Do something here!
                response = get_response(request)
                return response

        return middleware

Observera

Om du deklarerar en hybrid middleware som stöder både synkrona och asynkrona anrop, kanske den typ av anrop du får inte matchar den underliggande vyn. Django kommer att optimera anropsstacken för mellanvaran för att ha så få sync/async-övergångar som möjligt.

Även om du wrappar en asynkron vy kan du alltså bli anropad i synkront läge om det finns annan, synkron middleware mellan dig och vyn.

När du använder en asynkron klassbaserad middleware måste du se till att instanser är korrekt markerade som coroutine-funktioner:

    from asgiref.sync import iscoroutinefunction, markcoroutinefunction

    class AsyncMiddleware:
        async_capable = True
        sync_capable = False

        def __init__(self, get_response):
            self.get_response = get_response
            if iscoroutinefunction(self.get_response):
                markcoroutinefunction(self)

        async def __call__(self, request):
            response = await self.get_response(request)
            # Some logic ...
            return response

## Uppgradering av middleware i stil med före Django 1.10

class django.utils.deprecation.MiddlewareMixin

Django tillhandahåller `django.utils.deprecation.MiddlewareMixin` för att underlätta skapandet av middleware-klasser som är kompatibla med både `MIDDLEWARE` och den gamla `MIDDLEWARE_CLASSES`, och som stöder synkrona och asynkrona förfrågningar. Alla middleware-klasser som ingår i Django är kompatibla med båda inställningarna.

Mixinen tillhandahåller en `__init__()`-metod som kräver ett `get_response`-argument och lagrar det i `self.get_response`.

Metoden `__call__()`:

1. Anropar `self.process_request(request)` (om definierat).

2. Anropar `self.get_response(request)` för att hämta svaret från senare middleware och vyn.

3. Anropar `self.process_response(request, response)` (om definierat).

4. Returnerar svaret.

Om den används med `MIDDLEWARE_CLASSES` kommer metoden `__call__()` aldrig att användas; Django anropar `process_request()` och `process_response()` direkt.

I de flesta fall räcker det med att ärva från denna mixin för att göra en gammal middleware kompatibel med det nya systemet med tillräcklig bakåtkompatibilitet. Den nya semantiken för kortslutning kommer att vara harmlös eller till och med fördelaktig för den befintliga mellanprogramvaran. I några få fall kan en middleware-klass behöva ändras för att anpassas till den nya semantiken.

Detta är de beteendemässiga skillnaderna mellan att använda `MIDDLEWARE` och `MIDDLEWARE_CLASSES`:

1. Under `MIDDLEWARE_CLASSES` kommer varje middleware alltid att få sin metod `process_response` anropad, även om en tidigare middleware kortslöt genom att returnera ett svar från sin metod `process_request`. Under `MIDDLEWARE` beter sig middleware mer som en lök: de lager som ett svar går igenom på vägen ut är samma lager som såg begäran på vägen in. Om en mellanvara kortsluts är det bara den mellanvaran och de före den i `MIDDLEWARE` som kommer att se svaret.

2. Under `MIDDLEWARE_CLASSES` tillämpas `process_exception` på undantag som uppstår från en `process_request`-metod för mellanprogramvara. Under `MIDDLEWARE` gäller `process_exception` endast för undantag som uppstår från vyn (eller från `render`-metoden i en `TemplateResponse`). Undantag som tas upp från en mellanvara konverteras till lämpligt HTTP-svar och skickas sedan vidare till nästa mellanvara.

3. Under `MIDDLEWARE_CLASSES`, om en `process_response`-metod ger upphov till ett undantag, hoppas `process_response`-metoderna för alla tidigare mellanprogram över och ett `500 Internal Server Error` HTTP-svar returneras alltid (även om undantaget som gav upphov till t.ex. var en `Http404`). Under `MIDDLEWARE`, kommer ett undantag som uppstår från en middleware omedelbart att konverteras till lämpligt HTTP-svar, och sedan kommer nästa middleware i raden att se det svaret. Mellanprogram hoppas aldrig över på grund av att ett mellanprogram ger upphov till ett undantag.