1.The request/response lifecycle, ordering, and short-circuiting
Every middleware wraps the ENTIRE rest of the chain — its code before calling get_response(request) runs on the way IN (request processing), and its code after runs on the way OUT (response processing), for every single request, in the order MIDDLEWARE lists them going in and the REVERSE order coming back out. This is why MIDDLEWARE's order matters: SessionMiddleware must run before AuthenticationMiddleware (auth needs the session already loaded), and a middleware near the top of the list is also the last to see the response on the way out. Short-circuiting means a middleware can return an HttpResponse directly instead of calling get_response() — the request never reaches any middleware or view further down the chain, and the response starts unwinding back out immediately from that point.
Key features
- Middleware wraps the entire chain in ONE pass — code before get_response(request) runs on the way in, code after runs on the way out, for every request
- MIDDLEWARE order is the request-processing order going IN, and the reverse order for response processing coming OUT — a middleware near the top sees the request first and the response last
- SessionMiddleware must precede AuthenticationMiddleware in MIDDLEWARE — authentication depends on the session already being loaded, a concrete, load-bearing example of why order matters
- A middleware short-circuits by returning an HttpResponse instead of calling get_response(request) — the view and every middleware layer closer to the center never run for that request
- process_exception() (an older-style hook, still supported) and exception handling in a __call__-based middleware's try/except are how middleware can react to a view raising an unhandled exception, not just a normal return
- Function-based (using MiddlewareMixin or a plain closure) and class-based __call__ middleware are both valid, current styles — a middleware is fundamentally just a callable that takes get_response and returns a callable taking request
Request vs response processing, by position in MIDDLEWARE
- SecurityMiddleware — first in, last out
- SessionMiddleware — must precede AuthenticationMiddleware
- AuthenticationMiddleware — sets request.user
- view — the center — last in, first out
Command
class MyMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# request processing
response = self.get_response(request)
# response processing
return responseMiddleware wraps the whole chain in one onion-layered pass — MIDDLEWARE's order is the request-processing order going in, and the REVERSE order for response processing coming out. SessionMiddleware must precede AuthenticationMiddleware. Short-circuiting (returning a response instead of calling get_response()) is a sanctioned way to reject a request before it reaches the view or any later middleware.