Flask 请求上下文

应用上下文和请求上下文

flask 提供两种上下文:application contextrequest context

application context 又演化出来两个变量 current_appg

request context 则演化出来 requestsession

变量名上下文说明
current_app应用上下文当前应用的应用实例
g应用上下文处理请求时,用作临时存储对象,每次请求都会重设这个变量
request请求上下文请求对象,封装了客户端发出的HTTP的请求内容
session请求上下文用户会话,值为一个字典,存储请求之间需要记住的值。

请求上下文: 保存的是客户端与服务端之间的交互数据。

应用上下文: 保存的是 flask程序运行过程中,保存的一些配置信息,比如程序名,数据库连接,用户信息等。

current_app

current_app 表示当前项目的 app

Flask(__name__),则 app.name就是当前启动文件的名字

如果传入其他字符串,比如'flask_app',则print(app.name)print(app2.name) 就是'flask_app'

from flask import Flask,current_app
app = Flask(__name__)
print(app)
print(app.name)

@app.route("/")
def hello():
    app2 = current_app
    print(app2) # type <class 'werkzeug.local.LocalProxy'>
    print(app2.name)
    return "Hello Flask"

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

在终端执行python,进行交互

>>> from flask import Flask, current_app
>>> app = Flask(__name__)
>>> print(app)
<Flask '__main__'>

>>> app2 = current_app
# 这里会报错误

上面会报错,原来 flask内部维护了两个栈(线程隔离的),

  1. current_app指向了AppContext(应用上下文)中的栈顶

  2. request指向了RequestContext(请求上下文)栈顶

  3. 当请求进入的时候,Request被压入栈中,从而flask.request 指向了 当前访问的请求对象,

  4. 接下来会判断 AppContext栈顶是否为空 ,如果为空,则压入一个 AppContext对象 ,即app,则 current_app 也有了指向

所以我们在项目中使用不会报错,即当flask运行的时候没事,但是在python交互模式下会报错。

我们手动的将app压入栈

>>> from flask import Flask,current_app
>>> app = Flask(__name__)
>>> ctx=app.app_context()
>>> ctx.push()
>>> app2 = current_app
>>> app2 
<Flask '__main__'>        # 这里不会报错了
>>> app2.config['DEBUG']  # 看一下DEBUG模式,默认为Flask
False
>>> ctx.pop()             # 请求结束,从栈中删除

使用with 实现了__enter____exit__分别让AppContext对象,即app入栈和出栈

from flask import Flask, current_app
 
app = Flask(__name__)
print(app)
with app.app_context():
    app2 = current_app
    print(app2)

g

1.在flask中,有一个专门用来存储用户信息的g对象,g的全称的为global。
2.g对象在一次请求中的所有的代码的地方,都是可以使用的。

request 请求上下文

from flask import request

如我们经常使用的 request,它封装了客户端发送的HTTP请求

Django 中, 将它放到了每个请求函数中,每个请求函数第一个参数都是request

Flask 则直接导入就能用,这是因为Flask帮助我们做了隔离,request在当前请求线程中为一个全局变量,

而其他请求线程是不能直接访问的,只能访问自己的request。

多线程服务器会创建一个线程池,再从线程池中选择一个线程处理新的请求,请求结束,线程归还到线程池。

session

session['name'] = user.id # 可以记录用户信息
session.get('name')       # 获取用户信息
session.pop('user_id')    # 删除用户信息

一个小例子

from flask import Flask,session
app = Flask(__name__)
app.secret_key = "miyao"

@app.route("/set1")
def hello0():
    session["name"] = '张三'

    return "Hello 张三"

@app.route("/set2")
def hello1():
    session["name"] = '李四'
    return "Hello 李四"

@app.route("/get")
def hello2():
    user_name = session.get('name')
    print(user_name)
    return f"Hello session, {user_name}"

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

上面这段程序流程,

浏览器访问 localhost:5000/set1, 服务端session会将name='张三'存下来,且内置的在响应中加入cookies

浏览器访问 localhost:5000/get, 服务端通过浏览器传入的cookies信息,去session中找到我们的name='张三'

浏览器访问 localhost:5000/set2 服务端存下李四,并返回对应的session

浏览器访问 localhost:5000/get ,cookies(李四的),拿到李四信息并返回

cookies和session的原理这里就不写了。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页