Django之中间件
目录
一、说明
1、简述
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下。
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', "rbac.middleware.rbac.RbacMiddleware" # 注册自定义中间件 ]
2、用途
django中间件可用作下面:
用户登录
日志记录
crsf:对所有的post请求做了一个验证
session
权限管理
注意:
对于所有请求的批量做处理的时候用中间件
单独对某几个函数做处理的时候用装饰器
3、组成部分
与mange.py在同一目录下的文件夹 rbac/middleware下的rbac.py文件中的RbacMiddleware类
中间件中可以定义下面的方法,分别是:
- process_request(self,request)
- process_view(self, request, callback, callback_args, callback_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
(1)process_request和process_response的执行过程
(2)process_view的执行过程
(3)process_excepttion
当views的函数中出现错误时,就会执行process_exception方法
二、自定义中间件
1、创建中间件
class RequestExeute(MiddlewareMixin): def process_request(self,request): pass def process_view(self, request, callback, callback_args, callback_kwargs): i =1 pass def process_exception(self, request, exception): pass def process_response(self, request, response): return response
2、注册中间件
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', "rbac.middleware.rbac.RbacMiddleware" ]
三、测试
1、验证process_request、process_response,其中process_request无返回值
注册md
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', 'app01.middleware.test.Md1', 'app01.middleware.test.Md2', ]
自定义md,路径是app01/middleware/test.py
class Md1(MiddlewareMixin): #必须继承 def process_request(self,request): print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等") # 如果无返回值,就继续执行后续中间件和视图函数 # 如果有返回值,就执行自己的process_response和上面的response def process_response(self,request,response): print("md1====process_response1") return response #必须有返回值 class Md2(MiddlewareMixin): def process_request(self,request): print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等") def process_response(self,request,response): print("md2====process_response2") return response
附:继承的MiddlewareMixin,django已定义。
class MiddlewareMixin: def __init__(self, get_response=None): self.get_response = get_response super().__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response
结果
md1===process_request。在执行views.py内容之前可做一些验证、预操作等 md2====process_request2。在执行views.py内容之前可做一些验证、预操作等 这里是主逻辑index.html md2====process_response2 md1====process_response1
2、验证process_request、process_response,其中process_request有返回值
自定义md,路径是app01/middleware/test.py
class Md1(MiddlewareMixin): #必须继承 def process_request(self,request): print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等") # 如果无返回值,就继续执行后续中间件和视图函数 # 如果有返回值,就执行自己的process_response和上面的response return HttpResponse("md1====process_request的return值") def process_response(self,request,response): print("md1====process_response1") return response #必须有返回值 class Md2(MiddlewareMixin): def process_request(self,request): print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等") def process_response(self,request,response): print("md2====process_response2") return response
结果
md1===process_request。在执行views.py内容之前可做一些验证、预操作等
md1====process_response1
3、验证process_view,无return
自定义
class Md1(MiddlewareMixin): #必须继承 def process_request(self,request): print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等") # 如果无返回值,就继续执行后续中间件和视图函数 # 如果有返回值,就执行自己的process_response和上面的response # return HttpResponse("md1====process_request的return值") def process_response(self,request,response): print("md1====process_response1") return response #必须有返回值 def process_view(self, request, callback, callback_args, callback_kwargs): print("md1=====process_view") class Md2(MiddlewareMixin): def process_request(self,request): print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等") def process_response(self,request,response): print("md2====process_response2") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("md2=====process_view")
结果
md1===process_request。在执行views.py内容之前可做一些验证、预操作等 md2====process_request2。在执行views.py内容之前可做一些验证、预操作等 md1=====process_view md2=====process_view 这里是主逻辑index.html md2====process_response2 md1====process_response1
4、验证process_view,有return
class Md1(MiddlewareMixin): #必须继承 def process_request(self,request): print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等") # 如果无返回值,就继续执行后续中间件和视图函数 # 如果有返回值,就执行自己的process_response和上面的response # return HttpResponse("md1====process_request的return值") def process_response(self,request,response): print("md1====process_response1") return response #必须有返回值 def process_view(self, request, callback, callback_args, callback_kwargs): print("md1=====process_view") return HttpResponse("md1=====process_view") # 有return值 class Md2(MiddlewareMixin): def process_request(self,request): print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等") def process_response(self,request,response): print("md2====process_response2") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("md2=====process_view")
结果
md1===process_request。在执行views.py内容之前可做一些验证、预操作等 md2====process_request2。在执行views.py内容之前可做一些验证、预操作等 md1=====process_view md2====process_response2 md1====process_response1
4、验证process_exception
待续
5、验证process_template_responseprocess
process_template_response(self,request,response)
只有当views函数中返回的对象中具有render方法,是就会直接process_template_responseprocess