I am looking into django middleware codebase. I looked into following diagram
So, the diagram is quite clear.
But I have some questions
What happens when exception comes in process_request() middleware ? How is it handled ? Will the response_middleware be invoked ? Eg. if exception comes in process_view()
of AuthenticationMiddleware
, then will process_response()
of MessageMiddleware
be invoked ?
What happens when in process_response() middleware returns response? Eg. if process_view()
of AuthenticationMiddleware
returns respones, then will process_response()
of MessageMiddleware
be invoked ? OR it'll turn back from AuthenticationMiddleware
(ie, it'll invoke process_response()
of AuthenticationMiddleware
, but will not invoke process_response()
of MessageMiddleware
)
I have debugged the behaviour of django in 1.10 where new style middleware classes are used, but I am not familiar about old MIDDLEWARE_CLASSES
settings ?
For django 1.10:-
1) If process_request()
for AuthenticationMiddleware
returns response, then process_template_response()
and process_response()
will be invoked as show in the figure given below for all the middlewares.
2) If process_request()
for AuthenticationMiddleware
raises exception, then also the behavior will be the same.
Correct me, If I am wrong.
Thanks in Advance.
In Django, middleware is a lightweight plugin that processes during request and response execution. Middleware is used to perform a function in the application.
To activate a middleware component, add it to the MIDDLEWARE list in your Django settings. A Django installation doesn't require any middleware — MIDDLEWARE can be empty, if you'd like — but it's strongly suggested that you at least use CommonMiddleware .
Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering Django's input or output. Each middleware component is responsible for doing some specific function.
Middleware is like a middle ground between a request and response. It is like a window through which data passes. As in a window, light passes in and out of the house. Similarly, when a request is made it moves through middlewares to views, and data is passed through middleware as a response.
The official documentation could answer your first question if you work on django project before the version 1.10.
please read the paragraph : behavioral differences between using MIDDLEWARE and MIDDLEWARE_CLASSES
Under MIDDLEWARE_CLASSES, every middleware will always have its process_response method called, even if an earlier middleware short-circuited by returning a response from its process_request method. Under MIDDLEWARE, middleware behaves more like an onion: the layers that a response goes through on the way out are the same layers that saw the request on the way in. If a middleware short-circuits, only that middleware and the ones before it in MIDDLEWARE will see the response.
However MIDDLEWARE_CLASSES
has been removed since django v1.10, and new style of middleware workflow (using __call__()
instead) has been introduced since then, this allows each middleware (applied in MIDDLEWARE
) to internally determine whether to short-circuit by returning response back (with error status) and not invoking subsequent middlewares and view middleware on exception handling, in such case, the diagram in the question may not be always the case, especially if your project includes custom middlewares.
[side note], a middleware with short-circuiting on exception may look like this :
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
try:
# Code to be executed for each request before
# the view (and later middleware) are called.
do_something_but_raise_exception()
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called.
except WHATEVER_EXCEPTION as e:
# short-circuiting, because self.get_response() is not invoked,
response = generate_custom_response(e)
return response
[Side note]:
For what it's worth , middlewares in FastAPI are also structured in similar way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With