详解Django中间件执行顺序


Posted in Python onJuly 16, 2018

中间件

Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。

我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。

1 中间件的定义方法

定义一个中间件工厂函数,然后返回一个可以别调用的中间件。

中间件工厂函数需要接收一个可以调用的get_response对象。

返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。

def simple_middleware(get_response):
 # 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。

 def middleware(request):
  # 此处编写的代码会在每个请求处理视图前被调用。

  response = get_response(request)

  # 此处编写的代码会在每个请求处理视图之后被调用。

  return response

 return middleware

例如,在users应用中新建一个middleware.py文件,

def my_middleware(get_response):
 print('init 被调用')
 def middleware(request):
  print('before request 被调用')
  response = get_response(request)
  print('after response 被调用')
  return response
 return middleware

定义好中间件后,需要在settings.py 文件中添加注册中间件

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',
 'users.middleware.my_middleware', # 添加中间件
]

定义一个视图进行测试

def demo_view(request):
 print('view 视图被调用')
 return HttpResponse('OK')

执行结果

详解Django中间件执行顺序

注意:Django运行在调试模式下,中间件init部分有可能被调用两次。

2 执行流程

详解Django中间件执行顺序

3 多个中间件的执行顺序

  • 在请求视图被处理前,中间件由上至下依次执行
  • 在请求视图被处理后,中间件由下至上依次执行

详解Django中间件执行顺序

示例:

定义两个中间件

def my_middleware(get_response):
 print('init 被调用')
 def middleware(request):
  print('before request 被调用')
  response = get_response(request)
  print('after response 被调用')
  return response
 return middleware

def my_middleware2(get_response):
 print('init2 被调用')
 def middleware(request):
  print('before request 2 被调用')
  response = get_response(request)
  print('after response 2 被调用')
  return response
 return 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',
 'users.middleware.my_middleware', # 添加
 'users.middleware.my_middleware2', # 添加
]

执行结果

init2 被调用
init 被调用
before request 被调用
before request 2 被调用
view 视图被调用
after response 2 被调用
after response 被调用

总结:中间件的本质其实就是个装饰器,对于装饰器我之前的随笔里也详细说过,装饰器的本质其实就是个闭包

详解Django中间件执行顺序

对于装饰器来说,在这里程序从上到下执行,开始记录装饰器1-3,然后读到了函数的时候,装饰器开始装饰,把函数的引用传入装饰器中,从装饰器3开始往上装饰,所以这时候开始执行装饰器3的初始化,并把装饰完的函数当做一个新的函数,再次把新的引用传入到装饰器2,接着装饰器2进行初始化,再次把新的函数的引用传入到装饰器1进行装饰,这时候装饰器1的初始化开始,并开始执行,从而接下来的执行顺序为1-3执行装饰的内容,最后再执行本来的函数,达到一个对原有函数增加功能和特性的要求。

装饰器:从程序开始的顺序,从上到下读取----》从下到上装饰----》从上到下执行

在中间件中,执行顺序等同,只不过中间件装饰的是视图函数或者是试图类,会有一个init()初始化,为了便于理解我在说明装饰器顺序的时候,那里说的初始化就是现在的init(),也就是中间件在执行上也是从最接近函数或者类的中间件开始初始化,在中间件注册时,如果有多个中间件,程序按照从上到下的顺序来确认中间件,接着执行视图函数的时候,开始从下到上的进行init(),这里的初始化init()类似于Flask框架里四种请求勾子中的请求开始前执行一次的意思,从下到上执行完init后,再从上到下执行请求前所要执行的代码,请求完成后再从下往上执行请求后的代码。

中间件:从程序开始的顺序,从上到下读取----》从下到上初始化init()----》从上到下执行请求前----》视图的请求----》从下到上执行请求后

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
采用Psyco实现python执行速度提高到与编译语言一样的水平
Oct 11 Python
Python学习小技巧之列表项的推导式与过滤操作
May 20 Python
python实现批量解析邮件并下载附件
Jun 19 Python
对python:print打印时加u的含义详解
Dec 15 Python
python感知机实现代码
Jan 18 Python
python opencv实现图像边缘检测
Apr 29 Python
Python 200行代码实现一个滑动验证码过程详解
Jul 11 Python
python中dict使用方法详解
Jul 17 Python
基于python实现文件加密功能
Jan 06 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
Feb 28 Python
2021年值得向Python开发者推荐的VS Code扩展插件
Jan 25 Python
python中opencv实现图片文本倾斜校正
Jun 11 Python
转换科学计数法的数值字符串为decimal类型的方法
Jul 16 #Python
python 不以科学计数法输出的方法
Jul 16 #Python
Django配置celery(非djcelery)执行异步任务和定时任务
Jul 16 #Python
Python中的Django基本命令实例详解
Jul 15 #Python
完美解决python中ndarray 默认用科学计数法显示的问题
Jul 14 #Python
python爬取哈尔滨天气信息
Jul 14 #Python
Python for循环中的陷阱详解
Jul 13 #Python
You might like
《逃离塔科夫》——“萌新劝退,老手自嗨”的硬核FPS游戏
2020/04/03 其他游戏
基于HTTP长连接的"服务器推"技术的php 简易聊天室
2009/10/31 PHP
php中使用$_REQUEST需要注意的一个问题
2013/05/02 PHP
php strnatcmp()函数的用法总结
2013/11/27 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
phpstudy2018升级MySQL5.5为5.7教程(图文)
2018/10/24 PHP
javascript十个最常用的自定义函数(中文版)
2009/09/07 Javascript
JQuery的一些小应用收集
2010/03/27 Javascript
Javascript中的变量使用说明
2010/05/18 Javascript
nodejs中exports与module.exports的区别详细介绍
2013/01/14 NodeJs
javascript中BOM基础知识总结
2017/02/14 Javascript
javascript基本常用排序算法解析
2017/09/27 Javascript
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
2018/10/17 NodeJs
详解Vue路由自动注入实践
2019/04/17 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
vue子组件改变父组件传递的prop值通过sync实现数据双向绑定(DEMO)
2020/02/01 Javascript
Element MessageBox弹框的具体使用
2020/07/27 Javascript
python正则匹配查询港澳通行证办理进度示例分享
2013/12/27 Python
python matplotlib 注释文本箭头简单代码示例
2018/01/08 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
PyCharm永久激活方式(推荐)
2020/09/22 Python
python数据分析工具之 matplotlib详解
2020/04/09 Python
无需压缩软件,用python帮你操作压缩包
2020/08/17 Python
Python中实现一行拆多行和多行并一行的示例代码
2020/09/06 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
AVI-8手表美国官方商店:AVI-8 USA
2019/04/10 全球购物
南京某软件公司的.net面试题
2015/11/30 面试题
金融行业务员的自我评价
2013/12/13 职场文书
关于幼儿的自我评价
2013/12/18 职场文书
医院护士见习期自我鉴定
2014/04/10 职场文书
班组拓展活动方案
2014/08/14 职场文书
2014大四本科生自我鉴定总结
2014/10/04 职场文书
草房子读书笔记
2015/06/29 职场文书
2016年春季开学典礼新闻稿
2015/11/25 职场文书
教你快速开启Apache SkyWalking的自监控
2021/04/25 Servers
python中的装饰器该如何使用
2021/06/18 Python