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 获取进程pid号的方法
Mar 10 Python
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
Apr 16 Python
python脚本设置系统时间的两种方法
Feb 21 Python
Python文件操作,open读写文件,追加文本内容实例
Dec 14 Python
对Tensorflow中权值和feature map的可视化详解
Jun 14 Python
pytorch 改变tensor尺寸的实现
Jan 03 Python
使用TensorFlow搭建一个全连接神经网络教程
Feb 06 Python
python使用pyecharts库画地图数据可视化的实现
Mar 25 Python
Django Form设置文本框为readonly操作
Jul 03 Python
Python matplotlib读取excel数据并用for循环画多个子图subplot操作
Jul 14 Python
详解Python3 定义一个跨越多行的字符串的多种方法
Sep 06 Python
django中cookiecutter的使用教程
Dec 03 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中的UNICODE 编码与解码
2013/06/29 PHP
php简单实现快速排序的方法
2015/04/04 PHP
PHP实现RSA签名生成订单功能【支付宝示例】
2017/06/06 PHP
通过修改referer下载文件的方法
2008/05/11 Javascript
js实现可拖动DIV的方法
2013/12/17 Javascript
IE6已终止操作问题的2种情况及解决
2014/04/23 Javascript
JS辨别访问浏览器判断是android还是ios系统
2014/08/19 Javascript
谷歌浏览器调试JavaScript小技巧
2014/12/29 Javascript
jQuery1.9.1源码分析系列(十六)ajax之ajax框架
2015/12/04 Javascript
javascript精确统计网站访问量实例代码
2015/12/19 Javascript
JQuery遍历元素的父辈和祖先的方法
2016/09/18 Javascript
如何利用模板将HTML从JavaScript中抽离
2016/10/08 Javascript
JavaScript关联数组用法分析【概念、定义、遍历】
2017/03/15 Javascript
深入理解Nodejs Global 模块
2017/06/03 NodeJs
es6+angular1.X+webpack 实现按路由功能打包项目的示例
2017/08/16 Javascript
微信小程序实现页面跳转传值的方法
2017/10/12 Javascript
javascript中的隐式调用
2018/02/10 Javascript
vue+vant实现商品列表批量倒计时功能
2020/01/13 Javascript
[01:01:18]VP vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
[00:58]PWL开团时刻DAY5——十人开雾0换5
2020/11/04 DOTA
python 获取本机ip地址的两个方法
2013/02/25 Python
Python标准库os.path包、glob包使用实例
2014/11/25 Python
Python正则表达式知识汇总
2017/09/22 Python
Django如何将URL映射到视图
2019/07/29 Python
python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例
2020/02/26 Python
python数据库编程 Mysql实现通讯录
2020/03/27 Python
Python ckeditor富文本编辑器代码实例解析
2020/06/22 Python
Python调用ffmpeg开源视频处理库,批量处理视频
2020/11/16 Python
中国制造网:Made-in-China.com
2019/10/25 全球购物
工业设计专业推荐信
2013/10/29 职场文书
电子商务专员岗位职责
2013/12/11 职场文书
优秀中学生事迹材料
2014/01/31 职场文书
总经理人事任命书
2014/06/05 职场文书
创业计划书之酒店
2019/08/30 职场文书
Mysql 如何实现多张无关联表查询数据并分页
2021/06/05 MySQL
详解flex:1什么意思
2022/07/23 HTML / CSS