flask 的 g 和session 的区别怎样理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask 的 g 和session 的区别怎样理解相关的知识,希望对你有一定的参考价值。

最近一直在研究Flask,由于gfirefly中提供的Http接口使用了Flask,以前都是写一些游戏中简单的操作,最近涉及到Flask的方面比较多,所以就认真研究了下。对Flask的request context和app context略有心得,所以和小伙伴们分享一下Flask的request原理。
在我们视图中要使用request时只需要from flask import request就可以了
很好奇在多线程的环境下,是如何保证request没有混乱的
在flask.globals.py中
[python] view plain copy 在CODE上查看代码片派生到我的代码片
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError('working outside of request context')
return getattr(top, name)

_request_ctx_stack = LocalStack()
request = LocalProxy(partial(_lookup_req_object, 'request'))
session = LocalProxy(partial(_lookup_req_object, 'session'))
其实可以看到不管request还是session最后都是通过getattr(top, name)获取的,也就是说肯定有一个上下文
对象同时保持request和session。我们只要一处导入request,在任何视图函数中都可以使用request,
关键是每次的都是不同的request对象,说明获取request对象肯定是一个动态的操作,不然肯定都是相同的request。这里的魔法就是_lookup_req_object函数和LocalProxy组合完成的。
LocalProxy是werkzeug.local.py中定义的一个代理对象,它的作用就是将所有的请求都发给内部的_local对象
[python] view plain copy 在CODE上查看代码片派生到我的代码片
class LocalProxy(object):
def __init__(self, local www.hbbz08.com , name=None):
#LocalProxy的代码被我给简化了,这里的local不一定就是local.py中定义的线程局部对象,也可以是任何可调用对象
#在我们的request中传递的就是_lookup_req_object函数
object.__setattr__(self, '_LocalProxy__local', local)
object.__setattr__(self, '__name__', name)

def _get_current_object(self):
#很明显,_lookup_req_object函数没有__release_local__
if not hasattr(self.__local, '__release_local__'):
return self.__local()
try:
return getattr(self.__local, self.__name__)
except AttributeError:
raise RuntimeError('no object bound to %s' % self.__name__)

def __getattr__(self, name):
return getattr(self._get_current_object(), name)
参考技术A   session 是可以跨 request 使用的,session 的数据是经过加密后存储在 cookie 里的,用户每次 request 都会把这些 cookie 信息发回来,从而实现跨 request 使用。
g 是面向单个 request 的,一个 request 处理完,g 里的东西就没了。

Flask 框架中 上下文基础理念,包括cookie,session存储方法,requset属性,current_app模块和g模块

Flask中上下文,分为请求上下文和应用上下文。既状态留存 ,就是把变量存在某一个地方可以调用

请求上下文:实际就是request和session用法理念,既都是可以存储东西。

应用上下文:既变量共享,就是把东西存储在变量里可以打印预览,应用上下文包括

current_app模块和g模块
 
 
cookie方法增,查,删。
注:存储cookie时使用set_coooki方法存储key--calve形式数据,另一个参数max_age
  是指定的存活时间。
  
  调用cookie的方法是通过request模块的cookies属性的get方法,指定key来调用value
 
  删除cookie通过make_response对象内置的delete_cookie方法来指定key 来删除value
 
具体代码如下:
# -*- encoding: utf-8 -*-
# cooki相关操作依赖于make_respinse库
from flask import Flask, make_response, request

# 建立对象
app = Flask(__name__)
# 从配置文件导入配置
app.config.from_pyfile(\'config.ini\')


@app.route(\'/\')
def index():
    return \'这里是首页\'

# 存cooki方法
@app.route(\'/setcookie\')
def set_cookie():
    resp = make_response(\'存储cookie\')
    # 使用set_coooki方法存储key--calve形式数据,另一个参数是指定的存活时间
    resp.set_cookie("productname", \'[卫生纸,花生,男神鹏]\', max_age=3600)
    return resp


# 调用cooki
@app.route(\'/getcookie\')
def get_cookie():
    # 通过request模块的cookies属性的get方法,指定key来调用value
    resp = request.cookies.get(\'productname\')
    return resp


# 删除cookie的方法
@app.route(\'/delcookie\')
def del_cookie():
    # 通过make_response对象内置的delete_cookie方法来指定key 来删除value
    resp = make_response(\'删除cookie\')
    resp.delete_cookie(\'productname\')
    return resp


if __name__ == "__main__":
    app.run(debug=True)
View Code

session方法增,查,删。

注:在存储sesson时按字典键值对形式直接使用session对存储的内容赋值。如:session[\'username\'] = \'你好\'

  查询时也一样遵循字典查询方式 如:se = session[\'username\']   然后 return se

  删除时通过session的pop方法来删除指定的key来删除value 既:session.pop(\'username\')

具体代码如下:

# -*- encoding: utf-8 -*-
# session 是依赖于flask的session模块
# 如果想使用sessio模块,在配置里一定要配置session的key
from flask import Flask,session

# 建立对象
app = Flask(__name__)
# 从配置文件加载配置
app.config.from_pyfile(\'config.ini\')


@app.route(\'/\')
def index():
    return \'我是首页.session\'

# 存储session的方法


@app.route(\'/set_session\')
def set_session():
    # 直接使用session对存储的内容赋值
    session[\'username\'] = \'你好\'
    return \'存储session成功\'

# 调用session的方法
@app.route(\'/get_session\')
def get_session():
    # 通过esssion直接内容调用
    se = session[\'username\']
    return se

# 删除session的方法
@app.route(\'/del_session\')
def del_session():
    # 通过session的pop方法来删除指定的key来删除value
    session.pop(\'username\')
    return \'删除成功\'


if __name__ == "__main__":
    app.run()
View Code

request属性是Flask框架中请求上下文重要模块之一:我们可以通过requset包含的属性来查询访问者信息在后台打印。

具体代码如下:

# -*- encoding: utf-8 -*-
from flask import Flask, request

app = Flask(__name__)
app.config.from_pyfile(\'config.ini\')

@app.route(\'/\', methods=[\'get\', \'post\'])
def index():
    #  打印请求头信息
    print(request.headers)

    # 打印请求方式
    print(request.method)

    # 打印请求的url地址
    print(request.url)

    # 打印所有cookie信息
    print(request.cookies)

    # 打印网址参数信息
    print(request.args.get(\'id\'))

    # dict是查询某对象里边所有属性
    print(request.__dict__)
    
    return \'你好\'


if __name__ == "__main__":
    app.run(debug=True)
View Code

current_app模块和g模块在这里只做简单介绍:既current_app模块用来存储当前应用的具体配置信息,g既global用来存储公共变量 以下代码做了个工具函数,方便查看

注:使用工具类要导包  from 文件名 import 方法名

具体代码为:

# -*- encoding: utf-8 -*-
from flask import Flask, current_app, g
# 从自定义的工具类文件内部引入check_username方法
from utils import check_uesrname

# 创建对象
app = Flask(__name__)

# 载入配置文件
app.config.from_pyfile(\'config.ini\')


@app.route(\'/\')
def index():
    # current_app模块用来存储当前应用的具体配置信息
    print(\'打印名字:%s\' % current_app.name)
    print(\'打印详细信息:%s\' % current_app.__dict__)
    # 打印全局对象g里面自定义的属性username
    check_uesrname()

    return \'李云鹏是积云酒蒙子\'


if __name__ == "__main__":
    app.run()
View Code
# -*- encoding: utf-8 -*-
from flask import Flask,g

def check_uesrname():
    g.username = \'李云鹏是积云酒蒙子\'
    print(g.username)
View Code

 

以上是关于flask 的 g 和session 的区别怎样理解的主要内容,如果未能解决你的问题,请参考以下文章

flask之g对象

flask之g对象

flask session session已过期,再发送ajax请求如何处理?

Flask学习总结

flask-sqlalchemy 和sqlalchemy的区别

Flask上下文管理session原理和全局g对象