Django中间件
HTTP请求周期初识
在HTTP请求周期中,之前的了解是:用户请求->URL->view视图->url->用户
实际在用户请求和URL之间是中间件

Django 的中间件的本质是类,有几个中间件,就有经过几个类,每个类都有相应的方法。
Django中的中间件
Django的中间件在setting中MIDDLEWARE
中间件是有顺序的,按照setting中的从上到下顺序执行
在Django1.10以上的版本中,当请求从上到下执行,如到达csrf出现问题,会从同一级别的csrf返回。
在之前的版本中,请求到达csrf出现问题,会从最后一个中间件返回。

自定义中间件
可以在当前的中间件的基础上进行修改,也可以自己定制新的中间件
小功能:
自定义中间件:
- 继承MiddlewareMixin
- process_request 可以没有返回值,有返回值的时候直接从同级别的位置返回
- process_response 有三个参数,必须有返回值
中间件
1 2 3 4 5 6 7 8 9 10
| from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request): print("m1.request") def process_response(self, request, response): print("m1.response") return response
|
视图
1 2 3 4 5
| from django.shortcuts import render,redirect,HttpResponse def test(rquest): print('test') return HttpResponse("ok")
|
结果:
1 2 3
| m1.request test 视图函数的执行 m1.response
|
process_request有返回值的情况
1 2 3 4 5 6 7 8 9 10 11
| from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render,redirect,HttpResponse class M1(MiddlewareMixin): def process_request(self, request): print("m1.request") return HttpResponse('okokoko') def process_response(self, request, response): print("m1.response") return response
|
结果:没有执行视图函数
1 2
| m1.request m1.response 直接从自己的方法返回
|
注册中间件
按顺序执行
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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', 'm1.M1', ]
|
深入HTTP请求周期
首选要明白的是web框架的本质是socket,但是Django是没有的,默认的wsgiref,生产环境用的是uwsgi
WSGI(Web Server Gateway Interface)Web服务网关接口已经成为了一种规范
wsgi是Django开始的地方

自定义中间件view
下面的情况是执行完m1的request后执行m2的request.
执行view的时候重新返回m1的view,然后是m2的view
中间执行view视图函数
最后执行m2的response,m1的response
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request): print("m1.process_request") def process_view(self, request, callback, callback_args, callback_kwargs): print("m1.process_view") def process_response(self, request, response): print("m1.process_response") return response class M2(MiddlewareMixin): def process_request(self, request): print('m2.process_request') def process_view(self, request, callback, callback_args, callback_kwargs): print("m2.process_view") def process_response(self, request, response): print('m2.process_response') return response
|
结果:
1 2 3 4 5 6 7
| m1.process_request m2.process_request m1.process_view m2.process_view test m2.process_response m1.process_response
|
*在view中是用callback方法
通过callback找到了视图函数的名字,callback加括号就是执行视图函数一次
注意的是m1的process_view没有返回值的时候是执行一次view中的test函数
有返回值的时候m2的process_view不会执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request): print("m1.process_request") def process_view(self, request, callback, callback_args, callback_kwargs): print("m1.process_view") response = callback(request, *callback_args, **callback_kwargs) def process_response(self, request, response): print("m1.process_response") return response class M2(MiddlewareMixin): def process_request(self, request): print('m2.process_request') def process_view(self, request, callback, callback_args, callback_kwargs): print("m2.process_view") def process_response(self, request, response): print('m2.process_response') return response
|
结果:
1 2 3 4 5 6 7 8
| m1.process_request m2.process_request m1.process_view test # 这是callback执行的 m2.process_view test m2.process_response m1.process_response
|
process的方法
- process_request
- process_response 一定要有返回值
- process_view
- process_exception(错误异常)
- process_template
- 视图函数中有render方法才执行
- 自己写类进行封装
返回对象有render方法
1 2 3 4 5
| process_request(self,request) process_view(self, request, callback, callback_args, callback_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response)
|
中间件应用
对所有请求或一部分请求做批量处理
例如把所有的请求筛选,缓存中有,直接从缓存中拿