← Back to Django Course | Chapter 12: Signals & Middleware | Lesson 7 of 8

Middleware Order in Settings

Middleware order is like a line of checkpoints — the order they stand in decides who checks your request first.

Requests Go Top to Bottom

For an incoming request, Django runs each middleware's pre-view code in the order it's listed, top to bottom.

Example: Requests Go Top to Bottom

For an incoming request, Django runs each middleware's pre-view code in the order it's listed, top to bottom.

markup
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",          # 1st on request
    "django.contrib.sessions.middleware.SessionMiddleware",   # 2nd
    "myapp.middleware.CustomHeaderMiddleware",                # 3rd
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Responses Go Bottom to Top

On the way back out, the order reverses: the last middleware to touch the request is the first to touch the response.

Example: Responses Go Bottom to Top

On the way back out, the order reverses: the last middleware to touch the request is the first to touch the response.

markup
class OrderDemoMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        print("-> request enters here first (top of list)")
        response = self.get_response(request)
        print("<- response leaves here last (top of list)")
        return response
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Dependencies Between Built-in Middleware

Some built-in middleware relies on another running first — for example, AuthenticationMiddleware reads request.session, so SessionMiddleware must come before it.

Warning: AuthenticationMiddleware must always come after SessionMiddleware in the list.

Example: Dependencies Between Built-in Middleware

Some built-in middleware relies on another running first — for example, AuthenticationMiddleware reads request.session, so SessionMiddleware must come before it.

markup
MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Placing custom middleware before SecurityMiddleware or SessionMiddleware when it depends on sessions or security headers already being set up.
  2. Assuming response processing happens in the same order as request processing — it actually happens in reverse.
  3. Reordering MIDDLEWARE without testing, breaking authentication because AuthenticationMiddleware needs SessionMiddleware to run first.
Chapter Summary
  • MIDDLEWARE in settings.py is a top-to-bottom list for requests, and bottom-to-top for responses.
  • Some middleware depends on others running earlier, like AuthenticationMiddleware needing SessionMiddleware.
  • Placing custom middleware in the wrong position can silently break session or auth behavior.
  • When in doubt, add custom middleware near the end of the list, after Django's built-ins.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.