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

问题描述 投票:2回答:1

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

在该文件中,我们有一个名为MiddlewareMixin的类。这个类用来编写中间件类。虽然与弃用无关,为什么这个类在这条路径中写道?

python django middleware
1个回答
5
投票

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

Django的中间件“风格”已经改变。这个MiddlewareMixin在大多数情况下可以将旧式中间件类“转换”为新式中间件装饰器,如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

但是现在,中间件被视为围绕“底层中间件”的某种“装饰者”,并最终被视为观点。如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_requestprocess_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_viewprocess_exceptionprocess_template_response,这里不再使用。但我认为这些并不是非常“受欢迎”。

© www.soinside.com 2019 - 2024. All rights reserved.