假设我有以下类,受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'”时,他解释说执行的顺序是:
__ init __
方法触发(在服务器启动时)__ call __
方法触发(每次请求)process_view()
方法已触发self.get_response(request)
__ call __
语句开头
醇>
" __ call __
方法究竟是什么触发(在每个请求中)"意思?不会触发' __ call __
方法实际上触发了self.get_respone(request)
'自动调用另一个中间件或类?
Django文档指出:
在Django调用视图之前调用
process_view()
。
对我来说,这必须意味着Django会检查'SimpleMiddleware'
类的实例是否包含方法'process_view()'
然后触发它,然后继续调用__ call __()
方法,这称为观看'?否则,如果立即触发__ call __
方法,则不会赢得process_view()
'因为__ call __
方法调用视图(或下一个中间件)而错过了?
有人可以帮我理解执行过程吗? Django如何解决这个问题?
谢谢
答案 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添加了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_request(self, request, response):
# do stuff with request and/or response
将在两个世界都有效。