django中间件,在http请求 到达视图函数之前 和视图函数return之后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
看图理解中间件
django中间件的执行顺序如上图示
无论是在请求到达view视图之前还是在response返回给用户之前,我们都可以进行拦截到,然后做自己的处理然后在给view处理,或者返回给用户。
这里介绍django中间件可以定义的五种方法:
这个方法是执行在request请求到达view视图之前,它可以拦截下来,将用户的headers、body、meta已经用户要请求的路由等等后可以拦截到,然后处理自己需要的逻辑。
应用:
1、可以在这里打印日志,将用户请求的路由、携带的headers、传来的body、GET参数等全部打印到日志里面
2、可以在这里判断用户是否有权限进入这个路由,没有权限就可以将用户跳转到其他路由。
def process_request(self,request):
print('===============================================')
print('拦截请求的地址:',request.path)
request_dic = json.loads(request.body, encoding='utf-8')
print(request_dic)
(1)执行完所有中间件的request方法‘
(2)url匹配成功
(3)拿到 视图函数的名称、参数,(注意不执行) 再执行process_view()方法
(4)最后去执行视图函数
这个方法发生在已经走过路由,即将到达vie视图函数。
可以拿到view视图函数,这里的用法笔者目前也没有用到,后续用到再次追加。
这个方法,只有在视图函数的返回对象中有render方法才会执行!
并把对象的render方法的返回值返回给用户(注意不返回视图函数的return的结果了,而是返回视图函数 return值(对象)的render方法)
同样,这里的用法笔者目前也没有用到,后续用到再次追加。
这个方法在view视图里面出现未知的错误时会执行,
应用:
在view视图函数出现未知的错误时,将用户重定向到其他页面,防止用户界面出现错误导致的用户体验下降。
def process_exception(self,request,exception):
print('发生错误的请求地址',request.path,exception.__str__)
return render(request,'Home.html')
这个方法,执行在response返回给用户之前,开发者可以在这里将需要修改的response内容修改后,再次返回给用户。
应用:
例如笔者遇到需要处理用户的翻译问题,那么不可能在每个view视图函数里面再意义一一翻译,这样肯定是不可取的。那么就可以在这里response到达用户之前,判断语言环境之后将翻译处理好,然后返回给用户。
def process_response(self,request,response):
if request.META.get('HTTP_LANGUAGE') == 'en':
translation_file_path = os.path.dirname(os.path.abspath(__file__)) + '/translation_file.txt'
with open(translation_file_path,'r') as f:
trans_list = f.read().split('\n')
dic = json.loads(response.content, encoding='utf-8')
for item in trans_list:
if dic['message'] in item:
item_tran_list = item.split(';')
dic['message'] = item_tran_list[1]
f.close()
response.content = json.dumps(dic)
return response
最后放上笔者图片中使用到的中间件整体代码
from django.http import HttpResponse
import json,os
# 继承自一个文件
from django.shortcuts import render
from django.utils.deprecation import MiddlewareMixin
# 注意写完之后要在setings里面进行注册 在MIDDLEARE里面注册使用
class myMiddle(MiddlewareMixin):
def process_request(self,request):
print('===========================================')
print('拦截请求的地址:',request.path)
request_dic = json.loads(request.body, encoding='utf-8')
print(request_dic)
def process_exception(self,request,exception):
print('发生错误的请求地址',request.path,exception.__str__)
return render(request,'Home.html')
def process_response(self,request,response):
response_dic = json.loads(response.content,encoding='utf-8')
print(response_dic)
return response