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 相关文章推荐
在Python的web框架中编写创建日志的程序的教程
Apr 30 Python
Django中使用group_by的方法
May 26 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
Apr 11 Python
python编写朴素贝叶斯用于文本分类
Dec 21 Python
django js实现部分页面刷新的示例代码
May 28 Python
python3第三方爬虫库BeautifulSoup4安装教程
Jun 19 Python
python实现扫描ip地址的小程序
Apr 16 Python
django框架中ajax的使用及避开CSRF 验证的方式详解
Dec 11 Python
python 将dicom图片转换成jpg图片的实例
Jan 13 Python
基于Python数据分析之pandas统计分析
Mar 03 Python
解决Keras的自定义lambda层去reshape张量时model保存出错问题
Jul 01 Python
Python random模块的使用示例
Oct 10 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编程实现获取excel文档内容的代码实例
2011/06/28 PHP
js与jquery中获取当前鼠标的x、y坐标位置的代码
2011/05/23 Javascript
jQuery实现带动画效果的多级下拉菜单代码
2015/09/08 Javascript
Javascript学习之谈谈JS的全局变量跟局部变量(推荐)
2016/08/28 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
Bootstrap实现导航栏的2种方式
2016/11/28 Javascript
将JSON字符串转换成Map对象的方法
2016/11/30 Javascript
javascript中递归的两种写法
2017/01/17 Javascript
微信小程序 数据交互与渲染实例详解
2017/01/21 Javascript
把vue-router和express项目部署到服务器的方法
2018/02/21 Javascript
vue编译打包本地查看index文件的方法
2018/02/23 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
2018/04/26 jQuery
微信小程序实现swiper切换卡内嵌滚动条不显示的方法示例
2018/12/20 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
2020/09/21 Javascript
python使用urllib模块和pyquery实现阿里巴巴排名查询
2014/01/16 Python
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
2015/03/19 Python
django批量导入xml数据
2016/10/16 Python
Numpy数组转置的两种实现方法
2018/04/17 Python
解决Spyder中图片显示太小的问题
2018/04/27 Python
python开发准备工作之配置虚拟环境(非常重要)
2019/02/11 Python
Python实现RGB与HSI颜色空间的互换方式
2019/11/27 Python
html5自定义video标签的海报与播放按钮功能
2019/12/04 HTML / CSS
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
校园报刊亭创业计划书
2014/01/02 职场文书
党员学习十八大感想
2014/01/17 职场文书
同学聚会老师邀请函
2014/01/28 职场文书
大型营销活动计划书
2014/04/28 职场文书
活动倡议书范文
2014/05/13 职场文书
大学生就业自荐书
2014/06/16 职场文书
机电专业毕业生求职信
2014/07/01 职场文书
检讨书大全
2015/01/27 职场文书
通用员工手册范本
2015/05/14 职场文书
四年级语文教学反思
2016/03/03 职场文书
阿里云Nginx配置https实现域名访问项目(图文教程)
2021/03/31 Servers
如何理解python接口自动化之logging日志模块
2021/06/15 Python
Python编程编写完善的命令行工具
2021/09/15 Python