About

Django Middleware — The Onion Structure Wrapping Requests/Responses

Why MIDDLEWARE order matters and how chaining works internally

Requests enter: Security → Session → Common → Auth → View
Responses exit: View → Auth → Common → Session → Security

Like peeling an onion going in, wrapping it back going out.

Internal Implementation

get_response is the next link in the chain. Django iterates MIDDLEWARE list in reverse at startup, connecting each middleware's get_response to the next.

Why Order Matters

SessionMiddleware must precede AuthenticationMiddleware — Auth reads user info from session. Swap them and request.user is always Anonymous.

Key Points

1

MIDDLEWARE list order = request processing order (chained in reverse)

2

get_response(request) call executes next middleware/View

3

Request: outside→in, Response: inside→out (onion structure)

4

Session must come before Auth for request.user to work

Use Cases

Custom logging — wrap request/response to measure processing time CORS handling — CorsMiddleware adds response headers
← Django ORM Internals — Why QuerySets Are Lazy Django Signals — Event-Based Loose Coupling →