理解Django 中Call Stack机制的小Demo


Posted in Python onSeptember 01, 2020

1.工作流程

request/response模式下,request并不是直接到达view方法,view方法也不是将返回的response直接发送给浏览器的,而是request由外到里的层层通过各种middleware层,这个时候可以对request做一些事情,到最后一层也就是最内层时,得到view方法返回的response,然后再把这个response再由内到外层层传递出来,这时候可以对response做一些事情,如下图:

理解Django 中Call Stack机制的小Demo

2.原理

class SimpleMiddleware:
 def __init__(self, get_response):
  self.get_response = get_response
  # One-time configuration and initialization.
 
 def __call__(self, request):
  # Code to be executed for each request before
  # the view (and later middleware) are called.
 
  response = self.get_response(request)
 
  # Code to be executed for each request/response after
  # the view is called.
 
  return response

每个middleware都如上面代码一样,有两个必须的函数:(1)__init__(self,get_response),负责在web server启动时完成初始化,即建立与下一层middleware的联系.(2)__call__(self,request),在每次request下,被调用。

有三个可选的函数:(1)process_view:__init__和__call__对view 方法一无所知,而process_view给了通道(give access to)在调用view方法之前获晓view方法及其参数,如果出现了,则它在__call__调用后,在self.get_response(request)之前调用,因此可以触发view 方法。(2)process_exception:如果在view方法中出现异常,该函数可以提供机会来处理异常(3)process_template_response:在self.get_response(request)调用后,view方法结束后,提供修改response的机会,需要注意的是该函数仅仅在view方法返回的是TemplateResponse类的情况下有效,如果返回的是render() ,则该函数不被触发。

详见 https://docs.djangoproject.com/en/3.1/topics/http/middleware/

(3)供进一步理解call stack 机制的小demo(仅供参考)

import time
class Base:
 def __init__(self,get_response):
  self.get_response=get_response
 def __call__(self,request=None):
  self.pre()
  response=self.get_response(request)
  self.after()
  return response
 def pre(self):
  pass
 def after(self):
  pass
class Response:
 def __init__(self):
  pass
def view(request):
 return Response()
def startServer(callstackSets,view):
 callstackSets.reverse()
 last=callstackSets.pop(0)(view)
 for i in range(len(callstackSets)):
  last=callstackSets.pop(0)(last)
 return last
class A(Base):
 def pre(self):
  print('In A')
 def after(self):
  print('Out A ')
class B(Base):
 def pre(self):
  print('In B')
 def after(self):
  print('Out B ')
class C(Base):
 def pre(self):
  print('In C')
 def after(self):
  print('Out C ')
if __name__=='__main__':
 callstackSets=[A,B,C]
 calls=startServer(callstackSets,view)
 calls('req')

运行后:

理解Django 中Call Stack机制的小Demo

可以看到完成了既定的目标,request进来后,一层一层的进入,直到最内层C,调用view方法,得到response,然后将response从最内层一层一层的传递出来!

到此这篇关于理解Django 中Call Stack机制的小Demo的文章就介绍到这了,更多相关Django Call Stack机制内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python网络编程学习笔记(三):socket网络服务器
Jun 09 Python
详细讲解用Python发送SMTP邮件的教程
Apr 29 Python
python 环境变量和import模块导入方法(详解)
Jul 11 Python
Python实现图片转字符画的示例
Aug 22 Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 Python
查看django执行的sql语句及消耗时间的两种方法
May 29 Python
tensorflow 恢复指定层与不同层指定不同学习率的方法
Jul 26 Python
一文带你了解Python中的字符串是什么
Nov 20 Python
使用Python快乐学数学Github万星神器Manim简介
Aug 07 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
Jun 11 Python
用Python提取PDF表格的方法
Apr 11 Python
Pandas-DataFrame知识点汇总
Mar 16 Python
如何快速理解python的垃圾回收机制
Sep 01 #Python
Python Opencv图像处理基本操作代码详解
Aug 31 #Python
Python Matplotlib绘图基础知识代码解析
Aug 31 #Python
一些关于python 装饰器的个人理解
Aug 31 #Python
Python常用模块函数代码汇总解析
Aug 31 #Python
PyTorch 导数应用的使用教程
Aug 31 #Python
PyTorch安装与基本使用详解
Aug 31 #Python
You might like
PHP将XML转数组过程详解
2013/11/13 PHP
PHP微信开发之文本自动回复
2016/06/23 PHP
PHP Header用于页面跳转时的几个注意事项
2016/10/21 PHP
PHP Class SoapClient not found解决方法
2018/01/20 PHP
php爬取天猫和淘宝商品数据
2018/02/23 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
PHP FileSystem 文件系统常用api整理总结
2019/07/12 PHP
Yii框架参数配置文件params用法实例分析
2019/09/11 PHP
JavaScript高级程序设计(第3版)学习笔记11 内建js对象
2012/10/11 Javascript
Javascript学习笔记之数组的遍历和 length 属性
2014/11/23 Javascript
JavaScript中常用的六种互动方法示例
2015/03/13 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
2016/05/10 Javascript
AngularJS $injector 依赖注入详解
2016/09/14 Javascript
js实现rem自动匹配计算font-size的示例
2017/11/18 Javascript
Vue 页面状态保持页面间数据传输的一种方法(推荐)
2018/11/01 Javascript
ES6中Symbol、Set和Map用法详解
2019/08/20 Javascript
js实现内置计时器
2019/12/16 Javascript
一个简单的python程序实例(通讯录)
2013/11/29 Python
总结Python编程中三条常用的技巧
2015/05/11 Python
基于wxpython实现的windows GUI程序实例
2015/05/30 Python
Python用zip函数同时遍历多个迭代器示例详解
2016/11/14 Python
利用Python+阿里云实现DDNS动态域名解析的方法
2019/04/01 Python
浅谈pytorch torch.backends.cudnn设置作用
2020/02/20 Python
Python如何使用内置库matplotlib绘制折线图
2020/02/24 Python
Python openpyxl模块实现excel读写操作
2020/06/30 Python
用python批量移动文件
2021/01/14 Python
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
美国折衷生活方式品牌:Robert Graham
2018/07/13 全球购物
C语言中break与continue的区别
2012/07/12 面试题
优秀安全员事迹材料
2014/05/11 职场文书
领导干部保密承诺书
2014/08/30 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书
Vue通过懒加载提升页面响应速度
2021/05/10 Vue.js
pytorch加载预训练模型与自己模型不匹配的解决方案
2021/05/13 Python
你知道Java Spring的两种事务吗
2022/03/16 Java/Android
提高系统的吞吐量解决数据库重复写入问题
2022/04/23 MySQL