Django 中间件介绍,如何自定义中间件,5分钟get! Django 中间件是修改 Django request 或者 response 对象的钩子,可以理解为是介于 HttpRequest 与 HttpResponse 处理之间的一道处理过程。
浏览器从请求到响应的过程中,Django 需要通过很多中间件来处理,可以看如下图所示:

Django 中间件作用:
中间件组件配置在 settings.py 文件的 MIDDLEWARE 选项列表中。
配置中的每个字符串选项都是一个类,也就是一个中间件。
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # 安全相关 'django.contrib.sessions.middleware.SessionMiddleware', # 处理session 'django.middleware.common.CommonMiddleware', # 处理是否带斜杠的 'django.middleware.csrf.CsrfViewMiddleware', # 跨站请求伪造的处理 'django.contrib.auth.middleware.AuthenticationMiddleware', # auth 'django.contrib.messages.middleware.MessageMiddleware', # Message 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]# SessionMiddleware源码django.contrib.sessions.middleware.SessionMiddlewareprocess_request(self, request) # 请求来了process_response(self, request, response) # 请求走了会触发中间件方法
process_request(self,request)process_view(self, request, view_func, view_args, view_kwargs)process_exception(self, request, exception)process_response(self, request, response)自定义中间的步骤:
在 app 目录下新建一个 py 文件,名字自定义,并在该 py 文件中导入 MiddlewareMixin:
导入:from django.utils.deprecation import MiddlewareMixin
自定义的中间件类,要继承父类 MiddlewareMixin:
class MD1(MiddlewareMixin): pass在 settings.py 中的 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', 'app01.middlewares.MD1',]自定义中间件类的方法有:process_request 和 process_response

process_request 方法有一个参数 request,这个 request 和视图函数中的 request 是一样的。
process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象。
process_request 方法是在视图函数之前执行的。
当配置多个中间件时,会按照 MIDDLEWARE中 的注册顺序,也就是列表的索引值,顺序执行。
不同中间件之间传递的 request 参数都是同一个请求对象。
process_response 方法有两个参数,一个是 request,一个是 response,request 是请求对象,response 是视图函数返回的 HttpResponse 对象,该方法必须要有返回值,且必须是response。
process_response 方法是在视图函数之后执行的。
当配置多个中间件时,会按照 MIDDLEWARE 中的注册顺序,也就是列表的索引值,倒序执行。
示例
创建MyMiddleware.py为例,自定义中间件
'''视图'''def middleware(request): print('视图函数') return HttpResponse('ok')'''路由''' path('mymiddleware/', views.middleware)'''MyMiddleware.py'''from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import render, HttpResponseclass MD1(MiddlewareMixin): def process_request(self,request): print("md1 process_request 方法。", id(request)) # 在视图之前执行 def process_response(self, request, response): print("md1 process_response 方法。", id(request)) # 在视图之后执行 return response '''request的内存地址值是一样的'''class MD2(MiddlewareMixin): def process_request(self,request): print("md2 process_request 方法。", id(request)) # 在视图之前执行 def process_response(self, request, response): print("md2 process_response 方法。", id(request)) # 在视图之后执行 return response'''结果'''md1 process_request 方法。 2094137412800md2 process_request 方法。 2094137412800视图函数md2 process_response 方法。 2094137412800md1 process_response 方法。 2094137412800从下图看,正常的情况下按照绿色的路线进行执行,假设中间件1有返回值,则按照红色的路线走,直接执行该类下的 process_response 方法返回,后面的其他中间件就不会执行

process_view 方法格式如下:
process_view(request, view_func, view_args, view_kwargs)process_view 方法有四个参数:
view_args 和 view_kwargs 都不包含第一个视图参数(request)。
process_view 方法是在视图函数之前,process_request 方法之后执行的。
返回值可以是 None、view_func(request) 或 HttpResponse 对象。
class MD1(MiddlewareMixin): def process_request(self, request): print("md1 process_request 方法。", id(request)) #在视图之前执行 def process_response(self,request, response): :#基于请求响应 print("md1 process_response 方法!", id(request)) #在视图之后 return response def process_view(self,request, view_func, view_args, view_kwargs): print("md1 process_view 方法!") #在视图之前执行 顺序执行 #return view_func(request)
process_exception 方法如下:
process_exception(request, exception)参数说明:
process_exception 方法只有在视图函数中出现异常了才执行,按照 settings 的注册倒序执行。
在视图函数之后,在 process_response 方法之前执行。
process_exception 方法的返回值可以是一个 None 也可以是一个 HttpResponse 对象。
返回值是 None,页面会报 500 状态码错误,视图函数不会执行。
process_exception 方法倒序执行,然后再倒序执行 process_response 方法。
返回值是 HttpResponse 对象,页面不会报错,返回状态码为 200。
视图函数不执行,该中间件后续的 process_exception 方法也不执行,直接从最后一个中间件的 process_response 方法倒序开始执行。
若是 process_view 方法返回视图函数,提前执行了视图函数,且视图函数报错,则无论 process_exception 方法的返回值是什么,页面都会报错, 且视图函数和 process_exception 方法都不执行。
直接从最后一个中间件的 process_response 方法开始倒序执行:
class MD1(MiddlewareMixin): def process_request(self, request): print("md1 process_request 方法。", id(request)) #在视图之前执行 def process_response(self,request, response): :#基于请求响应 print("md1 process_response 方法!", id(request)) #在视图之后 return response def process_view(self,request, view_func, view_args, view_kwargs): print("md1 process_view 方法!") #在视图之前执行 顺序执行 #return view_func(request) def process_exception(self, request, exception):#引发错误 才会触发这个方法 print("md1 process_exception 方法!") # return HttpResponse(exception) #返回错误信息该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法
def process_template_response(self,request,response): print('我执行了') return responseclass Test: def __init__(self,status,msg): self.status=status self.msg=msg def render(self): import json dic={'status':self.status,'msg':self.msg} return HttpResponse(json.dumps(dic))def index(response): return Test(True,'测试')参考:中间件