中间件
这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
django的中间件是全局范围内处理django的请求和响应的框架级别的钩子
Django中处理请求和相应的框架级别的钩子,本质上是一个类,类定义了5个方法,特定时执行这些方法.
1、创建中间件流程
1. 在app下新建一个文件夹,Middlewares
2. 在文件夹下,定义中间件的类My_Middlewares.py
3. 编写中间件,一定要继承MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print(id(request))
print("MD1 request")
return HttpResponse("如果中间键里面有返回值,就不执行后面的视图函数,连中间键后面的也不执行")
4. 注册在settings.py里面的MIDDLEWARE中定义中间件(!中间件是从上往下执行,在由下往上)
MIDDLEWARE = [
'app.Middlewares.My_Middlewares.MD1',
# 'app.Middlewares.My_Middlewares.MD2',
]
2、中间件的5个方法和4个特征
执行时间、执行顺序、参数、返回值
2.1 process_request(请求之前)
process_request(self, request) #用来处理请求
执行时间:视图函数之前,路由匹配之前
执行顺序:
按照注册的顺序 顺序执行
参数:
request请求的对象和视图函数是同一个对象
返回值:
None 正常流程
HttpResponse(有返回值) 不执行后面的视图函数和路由匹配,连中间键后面的也不执行,直接返回给浏览器了,直接去执行当前中间件的`process_response`方法
2.2 process_response
process_response(self, request, response) #用来响应请求
执行时间:视图函数之后(如果里面有具体的返回值,就会覆盖视图函数里面的返回值,)
执行顺序:
先按照按照注册的顺序执行, 返回process_response的时候就倒序执行
参数:
request请求的对象和视图函数是同一个对象
response响应对象
返回值:
HttpResponse必须返回
2.3 process_view
process_view(self,request,view_func,view_args,view_kwargs) #用来处理视图函数
执行时间:视图函数之前,路由匹配之后
执行顺序:
按照注册的顺序 顺序执行
process_view方法是在process_request之后,视图函数之前执行的
参数:
request请求的对象和视图函数是同一个对象
view_func视图函数
view_args视图函数的位置参数 ()元组
view_kwargs视图函数的关键字参数 {}字典
返回值:
None 正常流程,原视图函数
HttpResponse
1.如果process_response 里面是return response
就返回中间件的process_view方法,视图函数都不执行
2.如果process_response 里面是return HttpResponse
执行最后一个中间件的process_response方法
2.4 process_exception
process_exception(self, request, exception) # 视图函数views有异常的时候,才执行
执行时间(触发条件):视图中有异常才执行
执行顺序:
按照注册的顺序 倒序执行
参数:
request请求的对象和视图函数是同一个对象
exception异常的对象
返回值:
None 当前的中间件没有处理异常,交给下一个中间件处理导演,如果都没有处理异常,就原生django处理异常
HttpResponse 当前中间件处理了异常,后面的中间件的process_Exception就不执行了,执行最后一个中间件的process_response方法
2.5 process_template_response
process_template_response(self, request,response) #用来处理请求
执行时间(触发条件):视图函数中返回的对象是TemplateResponse对象
执行顺序:
按照注册的顺序 倒序执行
参数:
request 请求的对象和视图函数是同一个对象
response 返回的TemplateResponse对象
返回值:
HttpResponse TemplateResponse的对象
过程处理模板的名字 参数
response.template_name
response.context_data
注意
process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)
3、自定义中间件示例
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MD1(MiddlewareMixin):
def process_request(self, request):
print("MD1 process_request")
# ret = HttpResponse("如果中间键里面有返回值,就不执行后面的视图函数,连中间键后面的也不执行")
# # return HttpResponse("如果中间键里面有返回值,就不执行后面的视图函数,连中间键后面的也不执行")
# return ret
def process_response(self, request, response):
print("MD1 process_response")
return response
def process_view(self, request, view_func, view_args, view_kwargs):
# print(request) # <WSGIRequest: GET '/index/1'>
# print(view_func) # <function index at 0x045FBB68>
# print(view_args) # ('1',)
# print(view_kwargs) # {'id': '2'}
print("MD1 process_view")
# return HttpResponse("MD1 process_view")
def process_exception(self,request,exception): #视图函数views有异常的时候,才执行
print("异常")
def process_template_response(self,request,response):
print("MD1 process_template_response")
return response
视图函数
from django.shortcuts import render, HttpResponse
from django.template.response import TemplateResponse
# Create your views here.
def index(request,*args,**kwargs):
print("index")
# return render(request,"index.html",{"user":"abcdefg"})
return TemplateResponse(request,"index.html",{"user":"abcdefg"})