1、中间件的定义


  • 中间件是Django 请求/响应 处理的钩子框架。(类似于vue中的生命周期钩子)
    • 它是一个轻量级的“插件”系统,用于全局改变Django输入输出请求响应
  • 中间件以的形式体现
  • 每个中间件组件负责做一些特定的功能。
    • 例如,Django包含一个中间件AuthenticationMiddleware,它使用会话将用户与请求关联

      流程示例:

      image.png

2、编写中间件

2.1、编写中间件类

中间件类必须继承自 django.utils.deprecation.MiddlewareMixin类
或者 django.middleware.common.MiddlewareMixin (都可以都是一个)

中间件类须实现下列五个方法中的一个或者多个:

process_request( self , request )

执行路由之前被调用,在每个请求上调用,返回 None 或者 HttpResponse对象

process_view( self , request , callback , callback_args , callback_kwargs )

调用视图之前被调用,在每个请求上调用,返回 None 或者 HttpResponse对象

process_response( self , request , response )

所有响应返回浏览器之前被调用,在每个请求上调用,必须返回 HttpResponse对象

process_exception( self , request , exception )

当处理过程中抛出异常时调用,返回一个 HttpResponse对象

process_template_response( self , request , response ) 不常用了解即可

在视图函数执行完,并且视图返回的对象中包含 render 方法时被调用;
该方法需要返回实现了 render 方法的响应对象

注意:

中间件的大多数方法在返回 None 时,表示忽略当前操作进入下一项事件;
当返回HttpResponse对象时,表示此请求结束,直接返回给客户端。

编写中间件示例:

一般在项目同级目录创建一个 Python Package 文件夹,文件夹名称自定义,一般命名为 middleware;
在middleware文件夹中,创建 一个python文件,文件名称自定义(本示例,命名为mymiddleware);
在mymiddleware.py文件中编写中间件类

  1. from django.utils.deprecation import MiddlewareMixin
  2. class MyMiddleWare1(MiddlewareMixin):
  3. def process_request(self, request):
  4. # 执行路由之前被调用,在每个请求上调用,返回 None 或者 HttpResponse对象
  5. print("MyMiddleWare1 process_request 被调用了~")
  6. def process_view(self, request, callback, callback_args, callback_kwargs):
  7. # 调用视图之前被调用,在每个请求上调用,返回 None 或者 HttpResponse对象
  8. print("MyMiddleWare1 process_view 被调用了~~")
  9. def process_response(self, request, response):
  10. # 所有响应返回浏览器之前被调用,在每个请求上调用,必须返回 HttpResponse对象
  11. print("MyMiddleWare1 process_response 被调用了~~~~")
  12. return response

3、注册中间件

settings.py 项目配置文件 中需要注册一下 自定义的中间件
注意:配置为数组,中间件被调用时,以“先上到下由下到上”的顺序调用

  1. # 用于注册中间件
  2. MIDDLEWARE = [
  3. 'django.middleware.security.SecurityMiddleware',
  4. 'django.contrib.sessions.middleware.SessionMiddleware',
  5. 'django.middleware.common.CommonMiddleware',
  6. # 'django.middleware.csrf.CsrfViewMiddleware',
  7. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  8. 'django.contrib.messages.middleware.MessageMiddleware',
  9. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  10. 'middleware.mymiddleware.MyMiddleWare1' #格式:(根目录的文件夹.文件名.类名)
  11. # 注册我们自定义的中间件
  12. # 中间件类的项目路径加入这个数据即可
  13. ]

注册中间件示例
image.png

多个中间件的执行顺序

让我们通过一次Django的一次请求和响应来试一下多个中间件的执行顺序

编写中间件类

  1. from django.utils.deprecation import MiddlewareMixin
  2. class MyMiddleWare1(MiddlewareMixin):
  3. # 测试多个中间件执行顺序的第1个中间件
  4. def process_request(self, request):
  5. print("MyMiddleWare1 process_request 被调用了~~~~~~")
  6. def process_view(self, request, callback, callback_args, callback_kwargs):
  7. print("MyMiddleWare1 process_view 被调用了~~~~~~")
  8. def process_response(self, request, response):
  9. print("MyMiddleWare1 process_response 被调用了~~~~~~")
  10. return response
  11. class MyMiddleWare2(MiddlewareMixin):
  12. # 测试多个中间件执行顺序的第2个中间件
  13. def process_request(self, request):
  14. print("MyMiddleWare2 process_request 被调用了>>>>>>>>>>")
  15. def process_view(self, request, callback, callback_args, callback_kwargs):
  16. print("MyMiddleWare2 process_view 被调用了>>>>>>>>>>")
  17. def process_response(self, request, response):
  18. print("MyMiddleWare2 process_response 被调用了>>>>>>>>>>")
  19. return response

注册这两个中间件类

  1. # 用于注册中间件
  2. MIDDLEWARE = [
  3. 'django.middleware.security.SecurityMiddleware',
  4. 'django.contrib.sessions.middleware.SessionMiddleware',
  5. 'django.middleware.common.CommonMiddleware',
  6. # 'django.middleware.csrf.CsrfViewMiddleware',
  7. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  8. 'django.contrib.messages.middleware.MessageMiddleware',
  9. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  10. 'middleware.mymiddleware.MyMiddleWare1', # 注册我们自定义的中间件
  11. 'middleware.mymiddleware.MyMiddleWare2' # 注册我们自定义的中间件
  12. ]

应用中的视图

  1. from django.shortcuts import render, HttpResponse,HttpResponseRedirect
  2. import json
  3. def test(request):
  4. # 测试中间件执行顺序的视图函数
  5. print("test视图函数,被调用了!!!!!!!!!!")
  6. data={"msg":"success!"}
  7. return HttpResponse(json.dumps(data))

绑定路由和视图

  1. from django.contrib import admin
  2. from django.urls import path
  3. from user import views
  4. urlpatterns = [
  5. path('admin/', admin.site.urls),
  6. path('test', views.test),
  7. ]

浏览器发起请求、获取响应
image.png
查看控制台输出,
image.png
多个中间件的执行顺序

  1. 先按照注册顺序“自上而下”,(进入视图函数之前,按照注册顺序执行)
  2. 执行完视图后
  3. 再按照注册顺序“自下而上”(在视图函数之后,按照注册顺序 由下而上 执行)

image.png

4、Django请求流程图

流程图.png

5、参考博客:

码迷:Django的中间件
http://www.mamicode.com/info-detail-2504161.html