zoukankan      html  css  js  c++  java
  • Flask 的整体流程

    封装 requestContext 对象, full_dispatch_request(视图函数 执行), response返回

    从app.run() 开始 -->>

    Flask的call方法-->>

    wsgi_app (封装RequestContext(request,session )对象到 localstack) -->>

    full_dispatch_request(视图函数 执行) -->>

    执行扩展(before_request) ,触发信号 -->>

    获取response -->>

    pop reqeust,session -- >>

    结束

    1)threading local 和 flask的自定义local对象 
    
            - 基于本地线程 可以实现,为了支持协程,自己定义了一个local对象
    
    (2) 请求到来
            封装  ctx = RequestContext(request,session)
                    ctx -- 放入 Local __storage__ { 'id':{stack:[ctx]} }
    
    (3)执行视图
            导入 request
    
            print(reqeust) -- >> localproxy __str__
            reqeust.method -- >> localproxy __getattr__
            reqeust + 1 -- >> localproxy __add__    
    
                调用 _lookup_req_object 函数  去local中的ctx 中 获取 reqeust session
    
    
    (4) 请求结束
            ctx.auto_pop
            ctx 从 local 中移除

    class RequestContext(object):
        def push(self):
            _request_ctx_stack.push(self)    # 将请求的相关数据 加到 local中,stack,local
    
            self.session = self.app.open_session(self.request)
            if self.session is None:
                self.session = self.app.make_null_session()
                #  将请求的相关数据 加到 local中,stack,local
                #  获取cookie中的随机字符串,检验是否存在,没有就生成一个
                #  根据随机字符串,获取服务端保存的 session的值
    
    
    class Flask(_PackageBoundObject):
    
    
        def __call__(self, environ, start_response):
            return self.wsgi_app(environ, start_response)
            
        def wsgi_app(self, environ, start_response):
            ctx = self.request_context(environ)   # 创建request对象
            ctx.push()                          # 处理 request 和 session
            error = None
            try:
                try:
                    response = self.full_dispatch_request()   #视图函数 执行
                return response(environ, start_response)
            finally:
                ctx.auto_pop(error)
    
        def full_dispatch_request(self):
             """
            self.try_trigger_before_first_request_functions()
            try:
                request_started.send(self)    # 触发信号,需要下载  blinker
                rv = self.preprocess_request()
                if rv is None:
                    rv = self.dispatch_request()
            return self.finalize_request(rv)      # 获取response 封装
    
        def finalize_request(self, rv, from_error_handler=False):
    
            response = self.make_response(rv)
            try:
                response = self.process_response(response)
            return response
    
    
        def process_response(self, response):
            ctx = _request_ctx_stack.top
            bp = ctx.request.blueprint
            funcs = ctx._after_request_functions
            if not self.session_interface.is_null_session(ctx.session):
                self.save_session(ctx.session, response)
            return response

    读书使人心眼明亮
  • 相关阅读:
    escape
    洛谷 P2158 【仪仗队】
    GIT学习----第五节:管理修改
    前端Webpack
    20 行 JS 代码,实现复制到剪贴板功能
    mysql表分区和分表的实现方式几种以及区别,什么时候用
    微信小程序----解析px、rpx、rem、vw实现页面布局
    微信小程序----相对路径图片不显示
    微信小程序----评价系统中的评星
    微信小程序----session_key失效导致的后台错误wxsp login api aesCbcUtil error info: pad block corrupted
  • 原文地址:https://www.cnblogs.com/ExMan/p/9875792.html
Copyright © 2011-2022 走看看