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)
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()
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)
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()
# -*- encoding: utf-8 -*- from flask import Flask,g def check_uesrname(): g.username = \'李云鹏是积云酒蒙子\' print(g.username)
以上是关于flask 的 g 和session 的区别怎样理解的主要内容,如果未能解决你的问题,请参考以下文章
flask session session已过期,再发送ajax请求如何处理?