上下文管理

请求上下文管理流程:

- 请求到来之后wsgi会触发__call__方法,由__call__方法再次调用wsgi_app方法
- 在wsgi_app方法中:
    - 首先将 请求相关+空session 封装到一个RequestContext对象中,即:ctx。
    - 将ctx交给LocalStack对象,再由LocalStack将ctx添加到Local中,Local结构:
        __storage__ = {
            1231:{stack:[ctx,] }
        }
    - 根据请求中的cookie中 提取 名称为sessionid对应的值,对cookie进行加密+反序列化,再次赋值给ctx中的session
    
    -> 执行视图函数
    
    - 把session中的数据再次写入到cookie中。
    - 将ctx删除
- 结果返回给用户浏览器
- 断开socket连接

概要

# 1 请求到来时候:
# ctx = RequestContext(self, environ) # self是app对象,environ请求相关的原始数据
    # ctx.request = Request(environ)
    # ctx.session = None

# 将包含了request/session的ctx对象放到“空调”
{
    1232:{ctx: ctx对象}
  1231:{ctx: ctx对象}
  1211:{ctx: ctx对象}
  1111:{ctx: ctx对象}
  1261:{ctx: ctx对象}
}

# 2 视图函数获取request/session:
    #视图函数在获取request / session时,内部隐含的操作是根据当前线程 / 协程的唯一标识取到ctx对象,再去ctx对象取request / session
    # 方式一:直接找LocalStack获取
         from flask.globals import _request_ctx_stack.top
        print(_request_cxt_stack.top.request.method)
    # 方式二:通过代理LocalProxy获取
            from flask import Flask,request
            print(request.method)

# 3 请求结束:
# 根据当前线程的唯一标记,将“空调”上的数据移除。

一  flask请求上下文管理流程图 

   三、请求上下文和app上下文:

- 请求上下文(ctx=RequestContext()):request/session
-  App上下文(app_ctx=AppContext()): app/g
    
- 程序启动:
    两个Local:
        local1 = {
        
        }
        
        local2 = {
        
        }

    两个LocalStack:
        _request_ctx_stack
        _app_ctx_stack
- 请求到来
    对数据进行封装:
        ctx = RequestContext(request,session)
        app_ctx = AppContext(app,g)
    保存数据:
        将包含了(app,g)数据的app_ctx对象,利用 _app_ctx_stack(LocalStack())将app_ctx添加到Local中
            storage = {
                1231:{stack:[app_ctx(app,g),]}
            }
        将包含了request,session数据的ctx对象,利用_request_ctx_stack(刘淞,LocalStack()),将ctx添加到Local中
            storage = {
                1231:{stack:[ctx(request,session),]}
            }
            
- 视图函数处理:   
    
    from flask import Flask,request,session,current_app,g

    app = Flask(__name__)
    @app.route('/index')
    def index():
        # 去请求上下文中获取值 _request_ctx_stack
        request.method # 找小东北获取值
        session['xxx'] # 找龙泰获取值
        
        # 去app上下文中获取值:_app_ctx_stack 
        print(current_app)
        print(g)        
        return "Index"

    if __name__ == '__main__':
        app.run()
        app.wsgi_app

- 结束
    _app_ctx_stack.pop()
    _request_ctx_stack.pop()

 问题:

1. Flask中g的生命周期?
        当每次请求进来的时候,会为每个请求创建一个g,在请求结束的时候g被移出;
        也就是说g只存在与当前请求的生命周期内
    
    2. g和session一样吗?
        不一样,g在请求结束的时候被清除了;session在请求结束的时候写入cookie中,请求来的时候可以从cookie中进行读取
    3. g和全局变量一样吗?
    
        不一样:
        全局变量在项目启动的时候被创建,g在请求来的时候被创建
        多线程,多线程来的时候操作全局变量会有问题,但g放在Local中,Local根据线程的唯一标识进行拆分开了
        全局变量设置完后会存放在内存中,没有被销毁,下次来还能读,而g被删掉了
    
    4.g的使用场景
        一次http请求内,如果先做一次操作再后做一个操作,后一个操作需要前面给它设置一些值的时候可以用到g

 二 flask-session  

pip3 install flask-session

1、使用

import redis
from flask import Flask,sessionfrom flask_session import Session

app = Flask(__name__)

app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.Redis(host='140.143.227.206',port=6379,password='1234')
Session(app)

@app.route('/login')
def login():
    session['user'] = 'alex'
    return 'asdfasfd'

@app.route('/home')
def index():
    print(session.get('user'))

    return '...'


if __name__ == '__main__':
    app.run()

2、原理

- session数据保存到redis
    session:随机字符串1:q23asifaksdfkajsdfasdf
    session:随机字符串2:q23asifaksdfkajsdfasdf
    session:随机字符串3:q23asifaksdfkajsdfasdf
    session:随机字符串4:q23asifaksdfkajsdfasdf
    session:随机字符串5:q23asifaksdfkajsdfasdf
- 随机字符串返回给用户。
    随机字符串


源码:
    from flask_session import RedisSessionInterface
原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13232651.html