环境:django:1.10 python: 2.7
简介
中间件是一个轻量级、底层的插件系统,可以介入 django 的请求和响应处理过程,修改 django 的输入和输出。
在 django 1.10(不包含)以前每个中间件是一个独立的python类,在 django1.10 以后需要继承 MiddlewareMixin(django 1.10后也可以写成函数,这里不考虑)。
每个中间件可以包含以下几个方法中的一个或多个:
__init__()、__call__()[django 1.10及以上]、process_request()、process_view()、process_template_response()、process_response()、process_exception().
示例:
在app目录下新建文件,名字随意,内容如下:
1 # coding: utf-8 2 from django.http import HttpResponse 3 try: 4 from django.utils.deprecation import MiddlewareMixin # Django 1.10.x 5 except ImportError: 6 MiddlewareMixin = object # Django 1.4.x - Django 1.9.x 7 8 class MyMiddleware(MiddlewareMixin): 9 def __init__(self, get_response): 10 self.get_response = get_response 11 # One-time configuration and initialization. 12 13 def __call__(self, request): 14 '''相当于process_view 和 proce_template_response 的合体 15 适用1.10以上的版本''' 16 # 调用 view 之前的代码, 17 print 'view before----------' 18 response = self.get_response(request) 19 print 'view after----------' 20 # 调用 view 之后的代码 21 return response 22 23 def process_request(self, request): 24 '''在urls.py之前调用,返回None或时HttpResponse对象''' 25 print 'urls before----------' 26 pass 27 28 def process_view(self, request, view_func, view_args, view_kwargs): 29 '''在views.py之前调用,返回None或时HttpResponse对象''' 30 print 'view1 before----------' 31 pass
32 33 def process_exception(self, request, exception): 34 '''在views.py中出现异常时被调用,返回None或时HttpResponse对象 35 注意:404错误属于url的异常,这里不能被捕捉到 36 各个版本通用''' 37 print 'exception before----------' 38 return HttpResponse(exception.message) 39 40 def process_template_response(self, request, response): 41 '''views.py 之后,渲染模板之前执行 42 返回实现了render方法的响应对象''' 43 print 'views after template before----------' 44 pass
45 46 def process_response(self, request, response): 47 '''在模板渲染完,返回浏览器前调用, 48 返回 HttpResponse 或 StreamingHttpResponse 对象''' 49 print 'template after----------' 50 return HttpResponse('template after----------')
激活:
在 settings.py 文件的 MIDDLEWARE(老版本MIDDLEWARE_CLASS)中添加:
'app名称.中间件文件名.中间件类名' # 中间用 “.” 相联
执行顺序:
- 若没有__call__()方法,按下图来执行:
- 若有__call__()方法,则只执行process_view()和process_response()方法:
__call__()的源码如下:
1 class MiddlewareMixin(object): 2 def __init__(self, get_response=None): 3 self.get_response = get_response 4 super(MiddlewareMixin, self).__init__() 5 6 def __call__(self, request): 7 response = None 8 if hasattr(self, 'process_request'): 9 response = self.process_request(request) 10 if not response: 11 response = self.get_response(request) 12 if hasattr(self, 'process_response'): 13 response = self.process_response(request, response) 14 return response