Skip to main content
 首页 » 编程设计

python之被中间件执行过程迷惑,DJANGO

2025年05月04日27mfryf

假设我有以下类,灵感来自 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 的书“Beginning Django”时,他解释说执行顺序是:

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

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

Django 文档指出:

process_view() is called just before Django calls the view.`

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

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

谢谢

请您参考如下方法:

你搞混了 old style (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 添加了 MiddlewareMixin ( source ):

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_response(self, request, response): 
        # do stuff with request and/or response 

将在两个世界中工作。