in path django.utils.deprecation.py
we have some class about deprecation warning for methods.
in that file we have a class called MiddlewareMixin
. this class used to write middleware classes. Although not related to deprecation, Why this class wrote in this path?
In short: it is a tool to turn deprecated middleware into new one, although it has some limitations.
Django's middleware "style" has changed. This MiddlewareMixin
can in most cases "convert" an old-styled middleware class to a new style middleware decorator, as is written in the documentation on Upgrading pre-Django 1.10-style middleware:
class django.utils.deprecation.MiddlewareMixin
(...)
In most cases, inheriting from this mixin will be sufficient to make an old-style middleware compatible with the new system with sufficient backwards-compatibility. The new short-circuiting semantics will be harmless or even beneficial to the existing middleware. In a few cases, a middleware class may need some changes to adjust to the new semantics.
In the "old days" (prior to django-1.10), middleware was written like:
class SomeMiddleware:
def process_request(self, request):
# ...
pass
def process_response(self, request, response):
# ...
return response
But nowadays, middleware is seen more as some sort of "decorator" around the "underlying middleware", and eventually the view. As specified in the documentation on the new middleware:
A middleware can be written as a function that looks like this:def simple_middleware(get_response): # One-time configuration and initialization. def middleware(request): # Code to be executed for each request before # the view (and later middleware) are called. response = get_response(request) # Code to be executed for each request/response after # the view is called. return response return middleware
By introducing a new "style", you can see the old middleware as "deprecated" itself, which is of course a pity because all middleware that was previously written now would be rendered invalid.
The MiddlewareMixin
is however capable to convert such old middleware in modern middleware, it does this by overriding the __call__
function, and thus call the process_request
and process_response
in between, like we can see in the source code [GitHub]:
class MiddlewareMixin: def __init__(self, get_response=None): self.get_response = get_response super().__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) response = response or self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response
Here we thus make the object callable by overriding the __call__
function, and thus mimicking how the def middleware(request)
in the new style works. If however in the old middleware, the __call__
is overridden as well, then this can of course result in some problems. Furthermore the old style middleware had some functions like process_view
, process_exception
, and process_template_response
, which are no longer used here. But I have the idea that these were not very "popular" anyway.
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