Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
The Request–Response Flow  ›  Capstone Project

Middleware and Routing

Routing Middleware 16 minMiddleware are layers listed in settings that every request passes through on the way in, before URL routing, and every response passes through on the way out, in reverse order.

Middleware and Routing

Every request to the cookbook, whatever its URL, needs the same chores: load the session, work out who the user is, check forms for forgery, add security headers. Writing those in every view would be madness. Django wraps all views in middleware, layers that every request passes through before routing even begins.

The rule

In from the top, out from the bottom; routing happens in the middle.

settings.MIDDLEWARE is an ordered list. A new project has:

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",
]

Picture them as layers of an onion around the view. The request goes through them top to bottom; then Django resolves the URL and calls the view; the response comes back bottom to top. Order matters: AuthenticationMiddleware sits below SessionMiddleware because it reads the user from the session.

A middleware is just a callable that receives the next layer, get_response:

# recipes/middleware.py
import time

def timing(get_response):
    def middleware(request):
        start = time.monotonic()              # on the way in
        response = get_response(request)      # everything below, including the view
        response["X-Elapsed"] = f"{time.monotonic() - start:.3f}"
        return response                       # on the way out
    return middleware

Add "recipes.middleware.timing" to the list and every response carries the header.

Two consequences for routing:

  • A middleware may return a response without calling get_response. Then the layers below it, the URL resolver and the view never run; the response travels back out through the layers above. That is how a "site under maintenance" switch can work.
  • Because the URL is resolved after the request middleware, a middleware can steer routing. Setting request.urlconf swaps the URL patterns for that request, for example a separate set for an api. subdomain.

Middleware classes can also define process_view(), which runs after the URL is resolved but just before the view, and is told which view was chosen.

The shortcut

To predict anything about middleware, draw the U: down the list, across to the view, back up the list. Whatever is higher in the list sees the request first and the response last.

GET /recipes/tomato-soup/ with timing at the topStep 1 of 4
  1. Down the list

    timing starts its clock, then security, sessions, common, CSRF, auth, messages, clickjacking.

Drills

Answer fast — trust the rule.

quick drill

In what order do responses pass through the MIDDLEWARE list?

quick drill

When does Django match the URL against urlpatterns?

quick drill

A maintenance middleware near the top returns a response without calling get_response. What runs next?

quick drill

Why must AuthenticationMiddleware come after SessionMiddleware?

Remember

  • In from the top, out from the bottom; routing and the view sit in the middle.
  • Draw the U to predict order; higher layers see the request first and the response last.
  • Trap: a middleware that returns early skips routing and the view entirely.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainTrace the whole trip

Trace a request for /recipes/tomato-soup/ through the cookbook from arrival to response, naming every stage in order. Then explain where a middleware that adds a timing header would sit, what order middleware run in, and what happens if a middleware returns a response early.