为什么在django.utils.deprecation.py中声明中间件mixin

vor*_*ack 6 python django middleware

在路径中,django.utils.deprecation.py我们有一些关于方法的弃用警告的类。

在该文件中,我们有一个名为的类MiddlewareMixin。该类用于编写中间件类。尽管与弃用无关,但为什么此类在此路径中编写?

Wil*_*sem 6

简而言之:它是一种将过时的中间件转换为新的中间件的工具,尽管它有一些局限性。

Django的中间件“样式”已更改。MiddlewareMixin在大多数情况下,这可以将旧风格的中间件类“转换”为新风格的中间件装饰器,如有关升级Django 1.10之前的中间件文档所述

class django.utils.deprecation.MiddlewareMixin

(...)

在大多数情况下,从该mixin继承将足以使旧式中间件与新系统兼容,并具有足够的向后兼容性。新的短路语义将对现有中间件无害甚至有益。在少数情况下,中间件类可能需要进行一些更改才能适应新的语义。

在“过去”(之前)中,中间件的编写方式如下:

class SomeMiddleware:

    def process_request(self, request):
        # ...
        pass

    def process_response(self, request, response):
        # ...
        return response
Run Code Online (Sandbox Code Playgroud)

但是如今,中间件更多地被看作是围绕“底层中间件”的某种“装饰器”,并最终被视为一种观点。如新中间件文档中所指定:

中间件可以编写为如下所示的函数:
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
Run Code Online (Sandbox Code Playgroud)

通过引入新的“样式”,您可以将旧的中间件本身视为“已过时”,这很遗憾,因为以前编写的所有中间件都将变为无效。

MiddlewareMixin然而能够这样转换中间件在现代中间件,它通过重写__call__功能,从而调用process_requestprocess_response介于两者之间,就像我们可以在看到源代码[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
Run Code Online (Sandbox Code Playgroud)

因此,在这里,我们通过覆盖函数使对象可调用__call__,从而模仿def middleware(request)了新样式中的工作方式。但是,如果在旧的中间件中__call__也重写了,那么这当然会导致一些问题。此外,旧的中间件具有,,和等功能process_view,此处不再使用。但是我认为这些都不是很“流行”。process_exceptionprocess_template_response

  • 这太令人困惑了。我认为它在那个包中,因为仅通过该包名称来判断,它本身就已被弃用。 (3认同)