Django 中间件的研究
2017-07-29 13:57
337 查看
闲来无事,看到MIDDLEWARE 这个列表,想一探究竟
先上几个参考链接:
涂伟忠自强学堂
戳这里这篇博客
官网文档中间件
上结论先
上代码(代码所在的文件在项目中的位置不重要,重要的是能找到中间件类的路径)
上配置
MIDDLEWARE中 中间件类所处的顺序很重要,决定了每个中间件类提供的钩子的执行顺序
调用的view函数
上运行结果
其他
以上 就是整个流程,当然,没有涉及process_template_response钩子列表
上个简图 input/output
每一个中间件都想一张过滤网
上个网络盗图
* 上第二个网络图
上面的介绍并不全面,还有很多细节没介绍,但不影响对请求/响应整个流程的理解
先上几个参考链接:
涂伟忠自强学堂
戳这里这篇博客
官网文档中间件
开篇
中间件是什么?中间件的本质是一个类实例对象或者一个函数对象,这些对象提供过滤请求、响应、处理异常等功能。重点关键字:过滤 1 中间件可以是类的形式也可以是函数的形式,见官网说明
上结论先
从请求到响应阶段 都可以进行拦截 第一阶段 处理 process_request 列表 返回None 或者HttpResponse对象 第二阶段 通过路由映射关系表获取视图函数地址 获得函数(进入视图预处理链process_view) 或者没有(404)--进入响应处理链 第三阶段 处理 process_view列表(前提是已经有匹配到的视图函数) process_view 返回None或者HttpReponse 第四阶段 处理视图函数 生成响应 第五阶段 处理异常检测 处理异常 返回响应或者None, None 表示交给下一层处理异常 第六阶段 处理 process_response 列表 不管从哪里发出的响应都要从响应链走,要么从中间走,要么从底层走 中间件类提供过滤请求、响应的钩子,即process_request、process_response等,所有钩子按照中间件类在中间件列表中的顺序组成新的钩子列表,process_response响应钩子、process_exception异常处理钩子是反向执行的
上代码(代码所在的文件在项目中的位置不重要,重要的是能找到中间件类的路径)
# 1.11 版本的兼容写法,当然你也可以自己手写一个类,不是很麻烦,我使用继承 # appname/middleware.py # 每一个类都可以根据需要提供不同的钩子,这些钩子组成钩子列表 from django.utils.deprecation import MiddlewareMixin class Row1(MiddlewareMixin): def process_request(self, request): print('row1 请求', request) # response = HttpResponse("row1 response") # return response def process_response(self, request, response): print('row1 响应', request, response) return response def process_view(self, request, view_func, view_args, view_kwargs): print('row1 view', view_func) class Row2(MiddlewareMixin): def process_request(self, request): print('row2 请求', request) def process_response(self, request, response): print('row2 响应', request, response) return response def process_view(self, request, view_func, view_args, view_kwargs): print('row2 view', view_func) def process_exception(self, request, exception): print('row2 exception', exception) return HttpResponse(exception); class Row3(MiddlewareMixin): def process_request(self, request): print('row3 请求', request) def process_response(self, request, response): print('row3 响应', request, response) if response.status_code == 404: response = HttpResponse('404') return response def process_view(self, request, view_func, view_args, view_kwargs): print('row3 view', view_func) def process_exception(self, request, exception): print('row3 exception', exception)
上配置
MIDDLEWARE中 中间件类所处的顺序很重要,决定了每个中间件类提供的钩子的执行顺序
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'booktest.middleware.Row1', 'booktest.middleware.Row2', 'booktest.middleware.Row3', ]
调用的view函数
# Create your views here. def index(request): # raise Exception('异常') return HttpResponse("<b>世界如此美妙<b>")
上运行结果
July 29, 2017 - 05:17:13 Django version 1.11, using settings 'test6.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. 生成应用 row1 请求 <WSGIRequest: GET '/'> row2 请求 <WSGIRequest: GET '/'> row3 请求 <WSGIRequest: GET '/'> row1 view <function index at 0x1044e36a8> row2 view <function index at 0x1044e36a8> row3 view <function index at 0x1044e36a8> row3 响应 <WSGIRequest: GET '/'> <HttpResponse status_code=200, "text/html; charset=utf-8"> row2 响应 <WSGIRequest: GET '/'> <HttpResponse status_code=200, "text/html; charset=utf-8"> row1 响应 <WSGIRequest: GET '/'> <HttpResponse status_code=200, "text/html; charset=utf-8"> [29/Jul/2017 05:17:55] "GET / HTTP/1.1" 200 24
其他
感兴趣的话可以手动抛出异常来看看效果 1 在process_request 阶段, 每个钩子都可以返回None或者HttpResponse对象(自己构造一个),如果返回None,则下一个钩子接着处理,直到URL关系映射表执行匹配操作;如果返回HttpResponse 则从当前中间件层开始反向返回结果,最核心层的view函数不会被执行,当前中间件层的下面中间件类提供的处理响应钩子也不会被执行(1.11版本) 2 当所有的process_request钩子执行完毕,都返回None,则进入路由关系映射匹配阶段,即根据请求路径找能处理响应的view函数,有两个结果:找到了--->进入process_view钩子列表处理阶段;没找到----->进入process_response钩子列表处理阶段 3 在process_view 处理阶段可以,每个钩子可以返回None也可以返回HttpResponse 对象,参上 4 在process_response 阶段,我们可以篡改响应,比如没找到视图函数,我们可以给捏造一个扔给客户 5 当process_request--->路由关系映射找到视图函数--->process_view 都处理完成了,并且找到了视图函数,中间没有使用钩子构造响应,则view函数开始工作:执行业务逻辑代码,从数据库拉去数据,给模板填坑,构造响应对象 6 5这个过程可能抛出异常,抛出异常则进入异常钩子列表process_exception,如果所有的异常处理钩子都不能处理异常,程序把异常通过process_response 钩子列表扔给客户
以上 就是整个流程,当然,没有涉及process_template_response钩子列表
上个简图 input/output
每一个中间件都想一张过滤网
上个网络盗图
* 上第二个网络图
收尾
我们拿这些中间件干什么呢?答:玩 认真的回答:那它做IP拦截,客户端设备识别,过滤恶意请求等等
上面的介绍并不全面,还有很多细节没介绍,但不影响对请求/响应整个流程的理解
相关文章推荐
- mysql中间件研究(Atlas,cobar,TDDL、sharding-jdbc)
- mysql中间件研究(Atlas,cobar,TDDL)
- 详解Django中间件执行顺序
- Django教程笔记之中间件middleware详解
- mysql中间件研究(Atlas,cobar,TDDL)
- django-中间件
- Django源码分析4:staticfiles静态文件处理中间件分析
- Django进阶之中间件
- Django 源码小剖: 初探中间件(middleware)
- 分布式消息队列中间件系列研究之阿堂教程(进阶篇)
- Django进阶之中间件
- django之创建第8个项目-数据库配置及同步研究
- 深入理解Django的中间件middleware
- mysql中间件研究
- [Django高级]理解django中的中间件机制和执行顺序
- mysql中间件研究(Atlas,cobar,TDDL)
- 缓存在中间件中的应用机制(Django)
- django-cms 代码研究(三)插件(plugs in)
- mysql中间件研究(Atlas,cobar,TDDL)
- django -- cbv,fbv,中间件