Writing Custom Middleware
In this page:
The Minimal Middleware Shape
Every middleware class needs an __init__ that stores get_response, and a __call__ that invokes it and returns the response.
Example: The Minimal Middleware Shape
Every middleware class needs an __init__ that stores get_response, and a __call__ that invokes it and returns the response.
class MinimalMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
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. #}
Adding Logic Before the View
Code placed before self.get_response(request) runs on the way in, and can attach extra data onto the request object for views to use later.
Example: Adding Logic Before the View
Code placed before self.get_response(request) runs on the way in, and can attach extra data onto the request object for views to use later.
class RequestTaggingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
request.is_mobile = "Mobile" in request.META.get("HTTP_USER_AGENT", "")
return self.get_response(request)
{# 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. #}
Adding Logic After the View
Code placed after self.get_response(request) runs on the way out, and can inspect or modify the response before it reaches the browser.
Example: Adding Logic After the View
Code placed after self.get_response(request) runs on the way out, and can inspect or modify the response before it reaches the browser.
class CustomHeaderMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response["X-Powered-By"] = "Django"
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. #}
Registering Your Middleware
A custom middleware class does nothing until its dotted path is added to the MIDDLEWARE list in settings.py.
Example: Registering Your Middleware
A custom middleware class does nothing until its dotted path is added to the MIDDLEWARE list in settings.py.
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"myapp.middleware.CustomHeaderMiddleware",
]
{# 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. #}
- Forgetting to return the response from __call__, which breaks every request in the project.
- Not calling self.get_response(request), which stops the view from ever running.
- Putting middleware logic in __init__ instead of __call__, so it only runs once at server startup instead of per request.
- Custom middleware is a class with __init__(self, get_response) and __call__(self, request).
- Always call self.get_response(request) and return its result to keep the chain working.
- Register custom middleware by adding its dotted path to MIDDLEWARE in settings.py.
- Per-request logic belongs in __call__, not __init__.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: