中间件执行过程让DJANGO感到困惑

Wil*_*son 1 python django middleware

假设我有以下类,受Django文档的启发:

class SimpleMiddleware(object):

    def __ init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):


        response = self.get_response(request)


        return response

    def process_view(self, request, view_func, view_args, view_kwargs):

        return None
Run Code Online (Sandbox Code Playgroud)

在阅读Daniel Rubio的书“ Beginning Django”时,他解释说执行的顺序是:

  1. __ init __ 触发方法(服务器启动时)
  2. __ call __ 触发方法(针对每个请求)
  3. 如果声明,则process_view()触发方法
  4. 查看方法以中的self.get_response(request)语句开头__ call __

__ call __(在每个请求上触发)方法”到底是什么意思?不会“触发”该__ call __方法实际上self.get_respone(request)自动触发“ ”,从而调用另一个中间件或类吗?

Django文档指出:

process_view() 在Django调用视图之前被调用。

对我来说,这将意味着Django检查'SimpleMiddleware'类的实例是否包含方法'process_view()',然后在继续调用该__ call __()方法之前触发该方法,即“调用视图”?否则,如果__ call __立即触发该方法,process_view()由于该__ call __方法调用视图(或下一个中间件),会不会遗漏' ' ?

有人可以帮我理解执行过程吗?Django如何做到这一点?

谢谢

sch*_*ggl 6

您正在混合使用旧样式(Django 1.10之前的版本)和新样式的中间件。新样式如下所示:

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # do stuff with request
        response = self.get_response(request)
        # do stuff with request and/or response
        return response
Run Code Online (Sandbox Code Playgroud)

与之等效的旧样式是:

class SimpleMiddleware:
    def process_request(self, request):
        # do stuff with request
    def process_response(self, request, response):
        # do stuff with request and/or response
Run Code Online (Sandbox Code Playgroud)

为了更轻松地将旧代码移植到新的工作方式中,django添加了MiddlewareMixin):

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)

现在,您对旧式中间件所做的全部工作就是使它们成为该mixin的子类。但是通常,新型中间件本身不具备或不需要这些process_...方法。但是例如:

from django.utils.deprecation import MiddlewareMixin

class SimpleMiddleware(MiddlewareMixin):
    def process_request(self, request):
        # do stuff with request
    def process_request(self, request, response):
        # do stuff with request and/or response
Run Code Online (Sandbox Code Playgroud)

将在两个世界都可以工作。

  • 但是 process_view() 和其他一些钩子一样,包含在新风格的中间件中吗?至少从文档中看起来是这样:https://docs.djangoproject.com/en/2.0/topics/http/middleware/ (4认同)