在路径django.utils.deprecation.py
中,我们有一些关于方法的弃用警告的类。
在该文件中,我们有一个名为MiddlewareMixin
的类。这个类用来编写中间件类。虽然与弃用无关,为什么这个类在这条路径中写道?
简而言之:它是一种将弃用的中间件转换为新的中间件的工具,尽管它有一些局限性。
Django的中间件“风格”已经改变。这个MiddlewareMixin
在大多数情况下可以将旧式中间件类“转换”为新式中间件装饰器,如documentation on Upgrading pre-Django 1.10-style middleware中所写:
class django.utils.deprecation.MiddlewareMixin
(...)
在大多数情况下,继承此mixin将足以使旧式中间件与新系统兼容,并具有足够的向后兼容性。新的短路语义对现有的中间件是无害的甚至是有益的。在少数情况下,中间件类可能需要进行一些更改以适应新的语义。
在“旧时代”(django-1.10之前),中间件被写成:
class SomeMiddleware:
def process_request(self, request):
# ...
pass
def process_response(self, request, response):
# ...
return response
但是现在,中间件被视为围绕“底层中间件”的某种“装饰者”,并最终被视为观点。如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
通过引入新的“样式”,您可以将旧的中间件视为“已弃用”本身,这当然很可惜,因为之前编写的所有中间件都将呈现为无效。
然而,MiddlewareMixin
能够在现代中间件中转换这样的旧中间件,它通过覆盖__call__
函数来实现这一点,因此在中间调用process_request
和process_response
,就像我们在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
因此,我们通过覆盖__call__
函数使对象可调用,从而模仿新样式中的def middleware(request)
如何工作。但是,如果在旧的中间件中,__call__
也被覆盖,那么这当然会导致一些问题。此外,旧式中间件有一些功能,如process_view
,process_exception
和process_template_response
,这里不再使用。但我认为这些并不是非常“受欢迎”。