对于中间件执行过程感到困惑,DJANGO

时间:2018-02-20 07:11:57

标签: 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

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

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

    " __ call __方法究竟是什么触发(在每个请求中)"意思?不会触发' __ call __方法实际上触发了self.get_respone(request)'自动调用另一个中间件或类?

    Django文档指出:

      在Django调用视图之前调用

    process_view()

    对我来说,这必须意味着Django会检查'SimpleMiddleware'类的实例是否包含方法'process_view()'然后触发它,然后继续调用__ call __()方法,这称为观看'?否则,如果立即触发__ call __方法,则不会赢得process_view()'因为__ call __方法调用视图(或下一个中间件)而错过了?

    有人可以帮我理解执行过程吗? Django如何解决这个问题?

    谢谢

1 个答案:

答案 0 :(得分:5)

您正在混淆old style(pre django 1.10)和new style中间件。新款式如下:

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

旧式的相当于:

class SimpleMiddleware:
    def process_request(self, request):
        # do stuff with request
    def process_response(self, request, response):
        # do stuff with request and/or response

为了便于将旧代码移植到新的处理方式,django添加了MiddlewareMixinsource):

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

现在你要用旧式中间件做的就是让它们成为这个混合的子类。但一般来说,新式中间件本身并不需要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

将在两个世界都有效。