zoukankan      html  css  js  c++  java
  • 理解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从最内层一层一层的传递出来!

    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    疫情环境下的网络学习笔记 python 5.8 数据库入门终章
    疫情环境下的网络学习笔记 python 5.7 navicat数据库,例题,sql注入
    疫情环境下的网络学习笔记 python 5.6 暂时看看
    疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键
    疫情环境下的网络学习笔记 python 5.4 数据库基础
    疫情环境下的网络学习笔记 python 4.30 初识数据库
    疫情环境下的网络学习笔记 python 4.29 网络小项目
    XJOI 夏令营501-511测试11 游戏
    XJOI 夏令营501-511测试11 统计方案
    CF1197D Yet Another Subarray Problem
  • 原文地址:https://www.cnblogs.com/johnyang/p/13592340.html
Copyright © 2011-2022 走看看