Middleware is code that is executed on every HTTP request processed by a Django application.
It is typically used for authentication, session management, internationalisation, logging, or security.
Because middleware runs for every request, it must be chosen and implemented carefully, as it introduces additional processing overhead to the request–response cycle.
To test quickly: Create a simple Django project or clone mysite, a basic Django project in my GitHub(38130):
git clone https://github.com/38130/mysite
The structure
mysite/
mysite/
settings.py
urls.py
middleware/
middleware.py
...
To create a custom middleware in Django, start by creating a folder named middleware inside the project subfolder, for example mysite/.
Inside the middleware/ directory, create a .py file containing the code that should be executed for each request.
Understanding the middleware structure
class MyFirstMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
A middleware is a Python class with two specific methods: __init__ and __call__.
This is how Django identifies and executes middleware.
Understanding the flow
__init__
Runs only once, when the Django application starts.
__call__
Runs once per HTTP request.
get_response(request) executes the next step in the middleware chain (which is usually another middleware or, at the end, the view).
It returns an HttpResponse, which can still be modified before being sent to the client.
settings.py
Once the middleware is implemented, it must be registered in the settings.py file by adding its full import path to the MIDDLEWARE list.
...
MIDDLEWARE = [
...
'mysite.middleware.middleware.MyFirstMiddleware',
]
From that point on, every incoming request will pass through the new middleware as part of Django’s request-processing pipeline.
