Django中间件相当于Django得门户: 1.请求来的时候需要先经过中间件才能到达真正的django后端 (浏览器给后端发送请求必须经过中间件) 2.响应走的时候最后也需要经过中间件才能发送出去 (后端给浏览器返回数据的时候也需要经过中间件) # Django自带7个中间件
研究Django中间件代码规律:
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', ] # 我们来看这7个中间件:他们其实并不是一个字符串,他们其实是一个模块的路径 'django.contrib.sessions.middleware.SessionMiddleware' 相当于: from django.contrib.sessions.middleware import SessionMiddleware
我们来看一下这几个中间件有什么规律:
Django支持程序员自定义中间件而且暴露给程序员五个可以自定义得方法: 1.常用: process_request process_response 2.了解: process_view process_template_response process_exception
第一步:在项目名或者应用名下创建一个任意名称的文件夹 第二步:在该文件夹内创建一个任意名称的py文件 第三步:在该py文件内需要书写类(这个类必须继承MiddlewareMixin) 然后在这个类里面就可以自定义五个方法了 (这五个方法并不是全部都需要书写,用几个写几个) 第四步:需要将类的路径以字符串的形式注册到配置文件中才能生效 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', '你自己写的中间件的路径2', '你自己写的中间件的路径3', ]
我们根据上面的步骤来自定义中间件来研究这5个方法:
自定义的mymidd.py
# 需要导入模块来继承该模块 from django.utils.deprecation import MiddlewareMixin class MyMiddleware1(MiddlewareMixin): def process_request(self,request): print('我是第一个自定义中间件里得process_request方法') class MyMiddleware2(MiddlewareMixin): def process_request(self,request): print('我是第二个自定义中间件里得process_request方法')
settings.py
# 注册自己的中间件(在应用下创建的,路径会有提示,但是如果在项目下创建的就没有提示了) MIDDLEWARE = [ 'app01.mymiddleware.mymidd.MyMiddleware1', 'app01.mymiddleware.mymidd.MyMiddleware2' ]
视图层views.py
def index(request): print('我是视图函数index') return HttpResponse('index')
我们在把中间件注册位置换一下看看打印是什么结果: MIDDLEWARE = [ 'app01.mymiddleware.mymidd.MyMiddleware2', 'app01.mymiddleware.mymidd.MyMiddleware1' ]
# 我们给自定义的中间件返回一个HttpResponse对象: class MyMiddleware1(MiddlewareMixin): def process_request(self,request): print('我是第1个自定义中间件里得process_request方法') return HttpResponse('我是第1个自定义中间件里得process_request方法的返回值')
总结process_request:
1.请求来的时候需要经过每一个中间件里面的process_request方法 结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行 2.如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件 3.如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行 而是直接原路返回(校验失败不允许访问...) # process_request方法就是用来做全局相关的所有限制功能
研究process_response
class MyMiddleware1(MiddlewareMixin): def process_request(self,request): print('我是第1个自定义中间件里得process_request方法') def process_response(self,request,response): print('我是第1个自定义中间件里得process_response方法') return response class MyMiddleware2(MiddlewareMixin): def process_request(self,request): print('我是第2个自定义中间件里得process_request方法') def process_response(self,request,response): print('我是第2个自定义中间件里得process_response方法') return response
1.响应走的时候需要结果每一个中间件里面的process_response方法 该方法有两个额外的参数request,response 2.该方法必须返回一个HttpResponse对象 1.默认返回的就是形参response 2.你也可以自己返回自己的 3.顺序是按照配置文件中注册了的中间件从下往上依次经过 如果你没有定义的话 直接跳过执行下一个
研究如果response返回自己的HttpResponse回事怎样的结果:
class MyMiddleware1(MiddlewareMixin): def process_request(self,request): print('我是第1个自定义中间件里得process_request方法') def process_response(self,request,response): print('我是第1个自定义中间件里得process_response方法') return HttpResponse('我是中间件1') class MyMiddleware2(MiddlewareMixin): def process_request(self,request): print('我是第2个自定义中间件里得process_request方法') def process_response(self,request,response): print('我是第2个自定义中间件里得process_response方法') return response # 结果:
研究二:
# 研究如果在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候是经过所有的中间件里面的process_response还是有其他情况 class MyMiddleware1(MiddlewareMixin): def process_request(self,request): print('我是第1个自定义中间件里得process_request方法') return HttpResponse('中间件1request') # 返回HttpResponse def process_response(self,request,response): print('我是第1个自定义中间件里得process_response方法') return response class MyMiddleware2(MiddlewareMixin): def process_request(self,request): print('我是第2个自定义中间件里得process_request方法') def process_response(self,request,response): print('我是第2个自定义中间件里得process_response方法') return response
研究process_view
# 具体使用: def process_view(self,request,view_name,*args,**kwargs): print(view_name,args,kwargs) print('我是第二个自定义中间件中的process_view方法') # 执行顺序: 路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该方法 顺序是按照配置文件中注册的中间件从上往下的顺序依次执行 # 所以在视图函数提交之前需要添加额外的操作可以在这个方法里做。
研究process_template_response
返回的HttpResponse对象有render属性的时候才会触发 顺序是按照配置文件中注册了的中间件从下往上依次经过
研究process_exception
当视图函数中出现异常的情况下触发 顺序是按照配置文件中注册了的中间件从下往上依次经过