django 之 中间件
中间件
一、定义:
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。 每个中间件都会负责一个功能。
django中的中间件(middleware),在django中,中间件其实就是一个类(继承MiddlewareMixin),在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,用于注册中间件,其中每一个元素就是一个中间件。
执行流程:
我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:
可以把中间件看作一层一层的过滤网,每层的类中都有处理不同问题的方法。也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。
注意点:
1.10版本的django直接在当前中间件中找到response返回;1.7或是1.8版本的,是跳到最后一个中间件找到response返回。
二、中间件的方法:(五个)
process_request(self,request) #一般是没有返回值,请求报错:实质上就是中间件resquest返回的错误信息! #用于处理request请求,一般没有返回值。若是有return返回值,就不在向下执行,直接通过当前中间件类中的response方法,把结果返回给浏览器。 #request执行,是在进行路由匹配,执行完之后,已经把所有路由系统中对应的视图函数全部读取。 process_view(self, request, view_func, view_func_args, view_func_kwargs) 参数: - view_func ----> 视图函数的函数名 - view_func_args, view_func_kwargs --->视图函数的参数。 #request请求完了后,返回从头再开始执行第一个view直到最后一个view, #用于处理视图函数,中间件中没有返回执行的视图函数,则会顺序执行到最后一个然后执行视图函数; #如果某个中间件中返回值为直接调用视图函数,则会从当前这个中间件直接跳到视图函数文件去执行视图函数。然后再从response顺序返回(response都会执行)。 process_exception(self, request, exception) #用于监测错误 - 参数:exception ---> 出错之后,返回给页面的信息,就不再让页面报错! process_response(self, request, response) #返回给浏览器的响应信息,必须有返回值。 return response 必须有返回值。return response process_template_response(self,request,response) #用于检测 视图函数中返回值,只有返回的是 render 才触发,其他类型不执行。
三、自定义中间件
多执行几次,多推敲下执行顺序!
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.utils.deprecation import MiddlewareMixin #导入模块 from django.shortcuts import render,HttpResponse class M1(MiddlewareMixin): def process_request(self,request): """ 已经完成了路由匹配 :param request: :return: """ print("m1.process_request") def process_view(self,request,callback,callback_args,callback_kwargs): """ 用于操作视图函数 :param request: :param callback: :param callback_args: :param callback_kwargs: :return: """ print("m1.process_view") print(callback) #查看执行的函数名字 response=callback(request,*callback_args,**callback_kwargs) return response def process_exception(self, request, exception): #异常相关处理 print("m1.process_exception") return HttpResponse("写错了!") #如果没有错误,直接执行response返回给客户端; # 若是有错误则执行exception处理异常(若某个中间件把异常处理了,就不再往下执行,直接跳转到最后一个中间件), # 然后返回到最后一个的中间件,再顺序执行response,返回给浏览器。 def process_template_response(self,request,response): print("m1.process_template_response") #对视图函数的返回值有一定要求,视图函数返回中如果有render方法,才执行! #返回类的一个对象,对象内封装了多个方法,会默认执行render方法 def process_response(self,request,response): """ 返回的响应信息 :param request: :param response: :return: """ 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_exception(self, request, exception): #异常相关处理 print("m2.process_exception") def process_template_response(self, request, response): print("m2.process_template_response") def process_response(self,request,response): print("m2.process_response") return response
找到 MIDDLEWARE 信息,在之后添加注册! 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', "md.M1", "md.M2", ]
from django.shortcuts import render,HttpResponse import JSON # Create your views here. # def test(request): # print("test") # int("asss") #用于错误测试 # return HttpResponse("....") #用以测试中间件process_template_response方法 class JSONResponse: def __init__(self,req,status,msg): self.request = req self.status = status self.message = msg def reder(self): ret={ "status":self.status, "message":self.message } return HttpResponse(JSON.dumps(ret)) def test(requset): return JSONResponse(requset,True,"错误信息")
应用:对所有请求或一部分请求做批量处理