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

时间:2018-10-21 08:15:25

标签: python django middleware

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

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

1 个答案:

答案 0 :(得分:3)

简而言之:它是一种将弃用的中间件转变为新的中间件的工具,尽管它有一些限制。

Django的中间件“样式”已更改。 MiddlewareMixin在大多数情况下可以将旧风格的中间件类“转换”为新风格的中间件 decorator ,如documentation on Upgrading pre-Django 1.10-style middleware所述:

  

class django.utils.deprecation.MiddlewareMixin

     

(...)

     

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

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

class SomeMiddleware:

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

    def process_response(self, request, response):
        # ...
        return response

但是,如今,中间件被更多地看作是围绕“底层中间件”的某种“装饰器”,并最终被视为一种观点。根据{{​​3}}中的规定:

可以将中间件编写为如下所示的函数:
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能够在现代中间件中转换这样的 old 中间件,它通过重写__call__函数来实现,从而调用process_requestprocess_response之间,就像我们在documentation on the new middleware中看到的那样:

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_viewprocess_exceptionprocess_template_response,在此不再使用。但是我有一个想法,就是这些都不是很“受欢迎”。