理解Django 中Call Stack机制的小Demo

1.工作流程

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

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')

运行后:

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

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

(0)

相关推荐

  • django 信号调度机制详解

    前言 Django中提供了"信号调度",用于在框架执行操作时解耦.通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者. 1.Django内置信号 Model signals pre_init # django的modal执行其构造方法前,自动触发 post_init # django的modal执行其构造方法后,自动触发 pre_save # django的modal对象保存前,自动触发 post_save # django的modal对象保存后,自动触发 pre_

  • 浅谈Django的缓存机制

    由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回. Django中提供了6种缓存方式: 开发调试 内存 文件 数据库 Memcache缓存(python-memcached模块) Memcache缓存(pylibmc模块) 通用配置 'TI

  • 3分钟看懂Python后端必须知道的Django的信号机制

    概念 django自带一套信号机制来帮助我们在框架的不同位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者(receivers). (感觉就很像Qt的信号与槽机制) 信号系统包含以下三要素: 发送者-信号的发出方 信号-信号本身 接收者-信号的接受者 Django内置了一整套信号,下面是一些比较常用的: Django内置信号 Model signals pre_init # django的modal执行其

  • 全面了解django的缓存机制及使用方法

    一.缓存目的 1.减小过载 2.避免重复计算 3.提高系统性能 二.如何进行缓存 三.缓存类型 四.缓存粒度分类 五.缓存的设置与使用 示例一: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } } 示例二: CACHES = { 'default': { 'BACKEND': 'django.core

  • django-利用session机制实现唯一登录的例子

    配置连接数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '数据库名称', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '10.18.62.2', 'PORT': '3306', } } 生成session表 python manage.py makemigrations python manage.py migrate 登录时记住保存用户登录信

  • Django的信号机制详解

    Django提供一种信号机制.其实就是观察者模式,又叫发布-订阅(Publish/Subscribe) .当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行. Django内置了一些信号,比如: django.db.models.signals.pre_save 在某个Model保存之前调用 django.db.models.signals.post_save 在某个Model保存之后调用 django.db.models.signals.pre_delete 在某个Model删除

  • django的autoreload机制实现

    在开发django应用的过程中,使用开发者模式启动服务是特别方便的一件事,只需要 python manage.py runserver 就可以运行服务,并且提供了非常人性化的autoreload机制,不需要手动重启程序就可以修改代码并看到反馈. 源码分析: runserver命令 命令行键入 python manage.py runserver 后,django会去寻找runserver这个命令的执行模块,最后落在 django\contrib\staticfiles\management\co

  • Django权限机制实现代码详解

    本文研究的主要是Django权限机制的相关内容,具体如下. 1. Django权限机制概述 权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮.因此,基于Django的开发,理清Django权限机制是非常必要的. 1.1 Django的权限控制 Django用user, group和permission完成了权限机制,这个权限机制是将属于model的某个permission赋予user或group,可以理解为全局的权限,即如果用户A对数

  • 理解Django 中Call Stack机制的小Demo

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

  • 全面理解java中的异常处理机制

    一.java异常总结: 异常就是程序运行时出现不正常运行情况 1.异常由来: 通过java的类的形式对现实事物中问题的描述,并封住成了对象 其实就是java对不正常情况描述后的对象体现 2.对于问题的划分有两种:一种是严重的问题,一种是非严重的问题 对于严重的,java通过Error类来描述 对于Error一般不编写针对性的代码对其进行处理 对于非严重的,java通过Exception类来描述 对于Exception可以使用针对性的处理方式进行处理 3.常见的异常有:数组角标越界异常,空指针异常

  • 深入理解Java中的SPI机制

    本文通过探析JDK提供的,在开源项目中比较常用的Java SPI机制,希望给大家在实际开发实践.学习开源项目提供参考. 1 SPI是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件. 整体机制图如下: Java SPI 实际上是"基于接口的编程+策略模式+配置文件"组合实现的动态加载机制. 系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接

  • 深入理解Django中内置的用户认证

    前言 本文主要给大家介绍了关于Django中内置用户认证的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 认证登陆 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户输入的密码,这样一来就要自己编写大量的代码. 事实上,Django已经提供了内置的用户认证功能. 在使用"python manage.py makemigrationss"和"python m

  • 由ArrayList来深入理解Java中的fail-fast机制

    1. fail-fast简介 "快速失败"也就是fail-fast,它是Java集合的一种错误检测机制.某个线程在对collection进行迭代时,不允许其他线程对该collection进行结构上的修改. 例如:假设存在两个线程(线程1.线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生f

  • 深入理解java中的拷贝机制

    前言 众所周知在Java中,拷贝分为深拷贝和浅拷贝两种.java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定义的clone方法为深拷贝. (一)Object中clone方法 如果我们new出一个新对象,用一个声明去引用它,之后又用另一个声明去引用前一个声明,那么最后的结果是:这两个声明的变量将指向同一个对象,一处被改全部被改.如果我们想创建一个对象的copy,这个copy和对象的各种属性完全相同,而且修改这个copy和原对象毫无关系

  • 深入理解Hibernate中的flush机制

    针对昨天同事遇到的hibernate的问题.算是hibernate最基本的东西.具了解,这个问题很多人遇到过,也很常见,却遇到了还经常会懵了. 为了加深印象,知其然,知其所以然. 之后单纯用原始的Hibernate框架做了一些验证,并且打开执行SQL打印输出台的,得出的结论: 前提是在同一事务中间: 1.利用sql语句, session.createSQLQuery(sql).executeUpdate();进行插入,输出台打印出sql插入语句: 再利用sql语句,进行session.creat

  • 深入理解MySQL中的事务机制

    使用数据库事务可以确保除事务性单元内的所有操作都成功完成.MySQL中的InnoDB引擎的表才支持transaction.在一个事务里,如果出现一个数据库操作失败了,事务内的所有操作将被回滚,数据库将会回到事务前的初始状态.有一些不能被回滚的语句:将在本文的最后讨论. 在一个web应用中,会很经常遇到需要使用事务的地方,要么希望若干语句都执行成功,要么都不执行,如果出现有些执行成功,而其他的失败将会导致数据损坏. 在这篇文章的例子中,我们使用下面的两张表"employee"和"

  • 全面了解Java中的CAS机制

    前言 在看到Java锁机制的时候,无意中看到了CAS这个词,然后在百度查找CAS看了很多文章始终没有看的太懂,今天又在Google上查找了一些资料,才算是真正弄清楚了CAS机制. 什么是CAS 在jdk 1.5中增加的一个最主要的支持是Atomic类,比如说AtomicInteger, AtomicLong,这些类可帮助最大限度地减少在多线程中对于一些基本操作(例如,增加或减少多个线程之间共享的值)的复杂性.而这些类的实现都依赖于CAS(compare and swap)的算法. 乐观锁和悲观锁

  • 深入理解js中this的用法

    this是js的一个关键字,随着函数使用场合不同,this的值会发生变化.但是总有一个原则,那就是this指的是调用函数的那个对象. 1.纯粹函数调用. function test() { this.x = 1; alert(x); } test(); 其实这里的this就是全局变量.看下面的例子就能很好的理解其实this就是全局对象Global.其实这里的this就是全局变量.看下面的例子就能很好的理解其实this就是全局对象Global. var x = 1; function test()

随机推荐