django框架中间件原理与用法详解


Posted in Python onDecember 10, 2019

本文实例讲述了django框架中间件原理与用法。分享给大家供大家参考,具体如下:

中间件:轻量级,介于 request和response之间的一道处理过程,在全局上改变了输入和输出

在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',
]

通过我们查看django的源码可以知道,中间件的使用方法有如下几种

process_request(self,request)
process_view(self,request,callback,callback_args,callbackkwargs)
process_template_response(self,request,response)
process_exception(self,request,exception)
process_response(self,request,response)

下面我们来通过自定义中间件来理解它们之间的顺序

1 最基本的一个中间件有两种方法:process_request     process_response

在project下面写一个py文件作为中间件文件

#my_middleware.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse,render
class Md1(MiddlewareMixin):
  def process_request(self,request):
      print("Md1请求")
  def process_response(self,request,response):
      print("Md1返回")
      return response
class Md2(MiddlewareMixin):
  def process_request(self,request):
      print("Md2请求")
  def process_response(self,request,response):
      print("Md2返回")
      return response

接着我们按照顺序分别加入settings

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',
  'my_middleware.Md1',
  'my_middleware.Md2',
]

定义一个views函数

def index(request):
  print("view视图")
  return HttpResponse("执行了view函数")

执行结果:(并且页面正常显示)

Md1请求
Md2请求
view视图
Md2返回
Md1返回

现在我们在request的后面加上一个 return

class Md1(MiddlewareMixin):
  def process_request(self,request):
      print("Md1请求")
      return Httpresponse("Md1中断")
  def process_response(self,request,response):
      print("Md1返回")
      return response
class Md2(MiddlewareMixin):
  def process_request(self,request):
      print("Md2请求")


 return Httpresponse("Md2中断")
def process_response(self,request,response):




print("Md2返回")



  return response

结果

Md1请求
Md1返回

#页面显示
Md1中断   ----》也就是没有执行views里面的函数

当两个中间件只有request和response的情况

1 request没有return的情况,按照顺序
  Md1 request  ---->  Md2 request 将view函数返回给用户 --->Md2 response --->Md1 response
2 request有return的情况:
Md1 request  ----> 查看有没有return,有的话返回给用户----->执行 Md1 response

没有return -------》Md2 request 查看有没有return,有的话返回给用户 ---->执行Md2 response  ---> Md1 response

没有return ,将view函数返回给用户  ---》执行Md2 response  ---> Md1 response

2 两个中间件,有 request  response   view

没有return的情况

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse,render
class Md1(MiddlewareMixin):
  def process_request(self,request):
      print("Md1请求")
      # return HttpResponse("Md1中断") #返回到前端
  def process_response(self,request,response):
      print("Md1返回")
      return response #不加return会报错
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md1 process_view",callback,callback_args,callback_kwargs)
class Md2(MiddlewareMixin):
  def process_request(self,request):
      print("Md2请求")
      # return HttpResponse("Md2中断")
  def process_response(self,request,response):
      print("Md2返回")
      return response
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md2 process_view",callback,callback_args,callback_kwargs)

结果:

Md1请求
Md2请求
Md1 process_view <function index at 0x000001B6C0A336A8> () {}
Md2 process_view <function index at 0x000001B6C0A336A8> () {}
view视图
Md2返回
Md1返回

有return的情况

def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md1 process_view",callback,callback_args,callback_kwargs)
    ret=callback(request)
    return ret
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md2 process_view",callback,callback_args,callback_kwargs)
    ret=callback(request) #执行views里面的函数  --------------------------》 callback(request) 相当于执行 views里面的函数
    return HttpResponse(ret)

结果:Md2的 process_view没有执行

Md1请求
Md2请求
Md1 process_view <function index at 0x000001F8AA3436A8> () {}
view视图
Md2返回
Md1返回

两个中间件 含有 request  response   view
Md1中process_view有return的话,不执行 Md2的process_view
    没有return和return在Md2的话,依次执行 Md1 process_view  ---> Md2 process_view  ---->view函数
无论有无return 返回给用户的都是views视图里面的函数

3 两个中间件 含有 request  response  view  exception

process_exception是当执行发生错误时,返回给用户一个东西

没有return的情况:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse,render
class Md1(MiddlewareMixin):
  def process_request(self,request):
      print("Md1请求")
  def process_response(self,request,response):
      print("Md1返回")
      return response #不加return会报错
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md1 process_view",callback,callback_args,callback_kwargs)
  def process_exception(self,request,exception):
    print("md1 process_exception")
class Md2(MiddlewareMixin):
  def process_request(self,request):
      print("Md2请求")
  def process_response(self,request,response):
      print("Md2返回")
      return response
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md2 process_view",callback,callback_args,callback_kwargs)
  def process_exception(self,request,exception):
    print("md2 process_exception")

结果:exception的内容没有打印

Md1请求
Md2请求
Md1 process_view <function index at 0x00000292CCBA46A8> () {}
Md2 process_view <function index at 0x00000292CCBA46A8> () {}
view视图
Md2返回
Md1返回

含有return的情况

from django.shortcuts import redirect,HttpResponse,render
class Md1(MiddlewareMixin):
  def process_request(self,request):
      print("Md1请求")
  def process_response(self,request,response):
      print("Md1返回")
      return response #不加return会报错
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md1 process_view",callback,callback_args,callback_kwargs)
  def process_exception(self,request,exception):
    print("md1 process_exception")
    return HttpResponse(exception)
class Md2(MiddlewareMixin):
  def process_request(self,request):
      print("Md2请求")
  def process_response(self,request,response):
      print("Md2返回")
      return response
  def process_view(self,request,callback,callback_args,callback_kwargs):
    print("Md2 process_view",callback,callback_args,callback_kwargs)
  def process_exception(self,request,exception):
    print("md2 process_exception")
    return HttpResponse(exception)

结果和没有return的时候一模一样,也就时exception里面的命令没有执行

我们现在认为的制造一个错误

def index(request):
  print("view视图")
  print(xinxin)  #这里是一个错误
  return HttpResponse("执行view函数")

都有return的情况

Md1请求
Md2请求
Md1 process_view <function index at 0x00000186896336A8> () {}
Md2 process_view <function index at 0x00000186896336A8> () {}
view视图
md2 process_exception  #执行了 Md2的exception,并且页面返回的是 return HttpResponse(exception)
Md2返回
Md1返回

Md2没有return,Md1有return的情况

Md1请求
Md2请求
Md1 process_view <function index at 0x00000276983B36A8> () {}
Md2 process_view <function index at 0x00000276983B36A8> () {}
view视图
md2 process_exception
md1 process_exception
Md2返回
Md1返回

exception总结:

当页面没有发生错误的时候,有无return,有多少个return都不会执行 exception里面的命令
当页面有错误时:倒着从excepton中找return  找到了就返回给用户 【Md2执行excepition,没有return的话,执行 Md1中的exception,有返回给用户,都没有的话,页面报错】
return HttpResponse(exception):中 exception存储了报错内容

django框架中间件原理与用法详解

最最最最后:

process_request 是顺序执行的
process_view   是顺序执行的
process_exception 是倒着查找的
process_response  是倒着执行的

希望本文所述对大家基于Django框架的Python程序设计有所帮助。

Python 相关文章推荐
pygame学习笔记(5):游戏精灵
Apr 15 Python
由Python运算π的值深入Python中科学计算的实现
Apr 17 Python
详解python进行mp3格式判断
Dec 23 Python
pandas DataFrame索引行列的实现
Jun 04 Python
tesserocr与pytesseract模块的使用方法解析
Aug 30 Python
详解python itertools功能
Feb 07 Python
使用Bazel编译TensorBoard教程
Feb 15 Python
Django media static外部访问Django中的图片设置教程
Apr 07 Python
jupyter lab文件导出/下载方式
Apr 22 Python
python+selenium+chrome批量文件下载并自动创建文件夹实例
Apr 27 Python
Python实现加密接口测试方法步骤详解
Jun 05 Python
python疲劳驾驶困倦低头检测功能的实现
Apr 04 Python
Django2 连接MySQL及model测试实例分析
Dec 10 #Python
python实现将视频按帧读取到自定义目录
Dec 10 #Python
django连接mysql数据库及建表操作实例详解
Dec 10 #Python
python 通过视频url获取视频的宽高方式
Dec 10 #Python
Python imageio读取视频并进行编解码详解
Dec 10 #Python
Python中Subprocess的不同函数解析
Dec 10 #Python
使用python-opencv读取视频,计算视频总帧数及FPS的实现
Dec 10 #Python
You might like
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
PHP中开启gzip压缩的2种方法
2015/01/31 PHP
php结合安卓客户端实现查询交互实例
2015/05/05 PHP
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
javascript 关闭IE6、IE7
2009/06/01 Javascript
JS实现在Repeater控件中创建可隐藏区域的代码
2010/09/16 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
js 中将多个逗号替换为一个逗号的代码
2014/06/07 Javascript
jQuery表格列宽可拖拽改变且兼容firfox
2014/09/03 Javascript
jquery操作对象数组元素方法详解
2014/11/26 Javascript
AngularJS用户选择器指令实例分析
2016/11/04 Javascript
Nodejs 获取时间加手机标识的32位标识实现代码
2017/03/07 NodeJs
详解Angular2 关于*ngFor 嵌套循环
2017/05/22 Javascript
jQuery阻止事件冒泡实例分析
2018/07/03 jQuery
微信小程序之自定义组件的实现代码(附源码)
2018/08/02 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
微信小程序与公众号实现数据互通的方法
2019/07/25 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
2019/11/15 Javascript
python hbase读取数据发送kafka的方法
2018/12/27 Python
Python叠加两幅栅格图像的实现方法
2019/07/05 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
Python进行统计建模
2020/08/10 Python
Python实现文件压缩和解压的示例代码
2020/08/12 Python
selenium切换标签页解决get超时问题的完整代码
2020/08/30 Python
如何利用python正则表达式匹配版本信息
2020/12/09 Python
css3动画过渡实现鼠标跟随导航效果
2018/02/08 HTML / CSS
Myprotein俄罗斯官网:欧洲第一运动营养品牌
2019/05/05 全球购物
水利公司纪检监察自我鉴定
2014/02/25 职场文书
小学语文教研活动总结
2014/07/01 职场文书
党员反对四风思想汇报范文
2014/10/25 职场文书
法院个人总结
2015/03/03 职场文书
2015学校图书管理员工作总结
2015/05/11 职场文书
2016年大学生党员公开承诺书
2016/03/24 职场文书
python实现MD5进行文件去重的示例代码
2021/07/09 Python
Win11更新失败并提示0xc1900101
2022/04/19 数码科技