文章目录
一、中间件的介绍
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能
中间件流程图
中间件有什么用
如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。
可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。
Django默认的中间件:(在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图)
python
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',
]
这七个中间件程序会在请求来时自上而下依次的处理request请求,在响应走时自下而上依次处理response响应。
中间件功能
网站访问频率的校验 用户权限的校验等全局类型的功能需求
前期我们要访问post请求,中间件的第四个字符串妨碍了简单post请求,初期阶段我们将其注释掉了
python
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',
]
这七个字符串实际上对应的是中间件程序存储的路径
我们顺着路径的文件,点进去可知源码
由上述图可知
1.七个中间件都继承了MiddlewareMixin类
2.都几乎有process_request和process_response函数
3.都必须传入参数
process_request需要传入request参数;
process_response需要传入request和response两个参数,必须返回response。
自定义中间
如何自定义中间件
1.创建存储自定义中间件代码的py文件或者目录(如果中间件很多)
2.参考自带中间件的代码编写类并继承
3.在类中编写五个可以自定义的方法
4.一定在配置文件中注册中间件才可以生效
编写自定义的中间件(在mymiddlie中编写MyMiddleware001)
编写好中间件,一定要去settings里的Middleware中注册自定义的中间件
中间件的顺序
我们只是定义了process_reqtest和process_response函数,我们想看看执行的顺序的,我们可以做一个小测试
mymiddle.py(自定义的中间件)
python
from django.utils.deprecation import MiddlewareMixin
class MyMiddleware001(MiddlewareMixin):
def process_request(self,request):
print('from MyMiddleware001 process_request')
def process_response(self,request,response):
print('from MyMiddleware001 process_response')
return response
class MyMiddleware002(MiddlewareMixin):
def process_request(self,request):
print('from MyMiddleware002 process_request')
def process_response(self,request,response):
print('from MyMiddleware002 process_response')
return response
当我们从网页向URL发送请求时,请求通过了网关接口到达了中间件,在中间件的执行过程是自上而下,从而经过路由层>>视图层>>>等,当响应是经过中间件的时候是自下而上的,返回给网关接口,再打包给浏览器,
打印结果
如果我们还想测试如果遇到HttpResponse对象,会怎么样?看下面的解释
django中间件两个基本方法
process_request
1.请求来的时候会从上往下依次经过每一个注册的中间件里面的该方法 如果没有则直接跳过
2.如果该方法自己返回了HttpResponse对象那么不再往后执行而是直接原路返回
如果请求遇到了process_request方法,该方法返回了HttpResponse对象,如下
python
class MyMiddleware001(MiddlewareMixin):
def process_request(self,request):
print('from MyMiddleware001 process_request')
return HttpResponse('你没有权限执行下面的中间件') # 遇到了HttpResponse对象
def process_response(self,request,response):
print('from MyMiddleware001 process_response')
return response
他经过的行径如黄色箭头,请求通过网关到中间件自上而下到达了中间件MyMiddleware001,就会直接执行MyMiddleware001的process_response方法,直接原路返回,不会走下面的中间件MyMiddleware002。
process_response
python
1.响应走的时候会从下往上依次经过每一个注册了的中间件里面的该方法 如果没有则直接跳过
2.该方法有两个先request和response 形参response指代的就是后端想要返回给前端浏览器的数据 该方法必须返回该形参 也可以替换
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
class MyMiddleware001(MiddlewareMixin):
def process_request(self,request):
print('from MyMiddleware001 process_request')
def process_response(self,request,response):
print('from MyMiddleware001 process_response')
# return response
return HttpResponse('中间1直接返回了,返回了response')
注意:
1.一个请求经过了中间件,如果在执行process_request方法的时候直接返回了HttpResponse对象那么会原路返回执行自定义中间件的process_response 不是执行所有。
2.在flask中,是从最底层中间程序的响应函数开始执行的
django中间件三个了解得方法
python
1.process_view
路由匹配成功之后执行视图函数/类之前自动触发(顺序同process_request)
2.process_exception
视图函数/类执行报错自动触发(顺序同process_response)
3.process_template_response
视图函数/类返回的HttpResponse对象含有render并且对应一个方法的时候自动触发(顺序同process_response)