中间件
Django中间件是修改Django request或者response对象的钩子,可以理解为是介于HttpRequest与HttpResponse处理之间的一道处理过程。
浏览器从请求到响应的过程中,Django需要通过很多中间件来处理。
Django中间件作用:
- 修改请求,即传送到view中的HttpRequest对象
- 修改响应,即view返回的HttpResponse对象
中间件组件配置在settings.py文件的MIDDLEWARE选项列表中。
配置中的每个字符串选项都是一个类,也就是一个中间件。
Django默认的中间件配置
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',
]
自定义中间件
中间件可以定义四个方法
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方法
process_request方法有一个参数request,这个request和视图函数中的request是一样的。
process_request方法的返回值可以是None也可以是HttpResponse对象。
- 返回值是None的话,按正常流程继续走,交给下一个中间件处理。
- 返回值是HttpResponse对象,Django将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒叙执行中间件,且执行的是视图函数之后执行的方法。
process_request方法是在视图函数之前执行的。
当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,顺序执行。
不同中间件之间传递的request参数都是同一个请求对象。
process_response
process_response方法有两个参数,一个是request,一个是response,request是请求对象,response是视图函数返回的HttpResponse对象,该方法必须要有返回值,且必须是response。
process_response方法是在视图函数之后执行的。
当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,倒序执行。
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 respons
如图,正常情况下按照绿色的路线进行执行,假设中间件1有返回值,则按照红色的路线走,直接执行该类下的process_response方法返回,后面的其他中间件就不会执行。
process_view
process_view方法格式
process_view(request, view_func, view_args, view_kwargs)
process_view方法四个参数
- request是HttpRequest对象
- view_func是Django即将使用的视图函数
- view_args是将传递给视图的位置参数的列表
- view_kwargs是将传递给视图的关键字参数的字典
process_view方法是在视图函数之前,process_request方法之后执行的。
返回值可以是None,view_func(request)或HttpResponse对象。
-
返回值是HttpResponse对象,Django将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法。
-
返回值是view_func(request),Django将不执行后续视图函数之前执行的方法,提前执行视图函数,然后再倒序执行视图函数之后执行的方法。
-
当最后一个中间件的process_request到达路由关系映射之后,返回到第一个中间件process_view,然后依次往下,到达视图函数。
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)
参数说明:
- request是HttpRequest对象
- exception是视图函数异常产生的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) #返回错误信息