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',
]
在最近的业务开发中用到了中间件,需求的场景是在执行任务之前先去判断该任务ID的审批状态 如果审批通过,给予执行,未通过,不执行,而Django的中间件来实现这一需求显得非常适合.
中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,extra operation,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
Django中间件必须是一个类,不需要继承任何类,并提供四个接口:
1、 process_request(self, request)该方法在请求到来的时候调用。
2、 process_view(self ,request, fnc , arg ,kwarg)在本次将要执行的View函数被调用前调用本函数。
3、 process_response(self,request,response)在执行完View函数准备将响应发到客户端前被执行。
4、 process_exception(self,request, exception) View函数在抛出异常时该函数被调用,得到的exception参数是实际上抛出的异常实例。通过此方法可以进行很好的错误控制,提供友好的用户界面。
要激活中间件,需要把它添加到Django 配置文件settings.py中的MIDDLEWARE中。
1.process_request(self,request)方法
这个方法是执行在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)
2.process_view(self, request, callback, callback_args, callback_kwargs)
(1)执行完所有中间件的request方法‘
(2)url匹配成功
(3)拿到 视图函数的名称、参数,(注意不执行) 再执行process_view()方法
(4)最后去执行视图函数
这个方法发生在已经走过路由,即将到达vie视图函数。
可以拿到view视图函数,这里的用法笔者目前也没有用到,后续用到再次追加。
3.process_template_response(self,request,response)
这个方法,只有在视图函数的返回对象中有render方法才会执行!
并把对象的render方法的返回值返回给用户(注意不返回视图函数的return的结果了,而是返回视图函数 return值(对象)的render方法)
同样,这里的用法笔者目前也没有用到,后续用到再次追加。
4.process_exception(self, request, exception)
这个方法在view视图里面出现未知的错误时会执行,
应用:
在view视图函数出现未知的错误时,将用户重定向到其他页面,防止用户界面出现错误导致的用户体验下降。
def process_exception(self,request,exception):
print('发生错误的请求地址',request.path,exception.__str__)
return render(request,'Home.html')
5.process_response(self, request, response)
这个方法,执行在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
参考原文:https://blog.csdn.net/haeasringnar/article/details/81589891