django中间件

448 阅读4分钟

中间件

这是我参与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, requestresponse)       #用来处理请求
执行时间(触发条件):视图函数中返回的对象是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"})
附:Django请求流程图

img