Flask快速入门(8) — 闪现flash
如果将a页面信息传到b页面,通常方法有:a.跳转至b页面时,以参数形式将数据传至b页面;b.将数据存至全局变量如session中传给b页面。
闪现实现了将数据信息传给其他页面,并且不用redirect跳转
使用方法:
a. 导入闪现:from flask import flash,get_flashed_message
b. 设置秘钥:app.secret_key = '任意字符串'
c. 设置:flash('第一个flash')
d. 获取:get_flashed_messages()
from flask import Flask,flash,get_flashed_messages
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdfsaf'
@app.route('/')
def index():
flash('第一个flash')
return 'index'
@app.route('/test1')
def test1():
data = get_flashed_messages()
data1 = get_flashed_messages()
return '获取的信息:%s,%s'%(data,data1)
@app.route('/test2')
def test2():
data = get_flashed_messages()
return '获取的信息:%s'%data
if __name__ == '__main__':
app.run()
问题:为什么要设置秘钥呢?以及设置和获取的函数内部是如何实现?从源码上做了简要的分析
flash源码
def flash(message, category="message"):
flashes = session.get("_flashes", []) # 从session中获取_flashes,没有则为空列表
flashes.append((category, message))
session["_flashes"] = flashes # 将(category, message)以元组的形式添加到flashes中,设置session存入cookie中
message_flashed.send(
current_app._get_current_object(), message=message, category=category
) # 发送信号
总结:
(1)flash必须要给message传值。不传category时则默认为message
(2)flash中用到了session存取值,所以要给他设置秘钥
(3)设置的flash数据都是列表中套元组的形式,元组的第一个数是类别,第二个数是值
get_flashed_messages源码
def get_flashed_messages(with_categories=False, category_filter=()):
flashes = _request_ctx_stack.top.flashes # 这是从请求上下文中获取flashes,后续博客会介绍请求上下文。请求刚到时获取的是None
if flashes is None:
# 在flash('xxx'),session['_flashes'] = flashes,如果有则从session中删除_flashes并赋值给 _request_ctx_stack.top.flashes = flashes = session['_flashes'],否则为空列表
_request_ctx_stack.top.flashes = flashes = (
session.pop("_flashes") if "_flashes" in session else []
)
if category_filter:
# 过滤;flashes是[(category,message),]这种形式的数据。过滤出你要取出的message
flashes = list(filter(lambda f: f[0] in category_filter, flashes))
if not with_categories:
# 如果不带有过滤字段,则返回所有的flashes值
return [x[1] for x in flashes]
return flashes
总结:
# 设置两个flash,第一个默认category为message,第二个category为two
flash('第一个flash')
flash('第二个flash','two')
with_categories:是否带上category,category_filter:返回为该类名的flash值
(1)get_flashed_messages():with_categories默认为False,category_filter默认为(),返回的值是 ['第一个flash', '第二个flash']
(2)get_flashed_messages(with_categories=True):返回的值是 [('message', '第一个flash'), ('two', '第二个flash')],带上类名
(3)get_flashed_messages(category_filter='two'):返回的值是 ['第二个flash'],过滤出类名为two的flash值。过滤多个分类时用元组或列表
(4)get_flashed_messages(with_categories=True,category_filter=['two','message']):返回的值是 [('message', '第一个flash'), ('two', '第二个flash')]
扩展
在同一个请求中可以多次获取flash值,即可以多次调用get_flashed_messages()。而在第二个请求中get_flashed_messages()获取到的就是个[]
@app.route('/test1')
def test1():
# 同一请求多次调用get_flashed_messages方法
data = get_flashed_messages()
data1 = get_flashed_messages()
return '获取的信息:%s,%s'%(data,data1)
@app.route('/test2')
def test2():
# 在发起/test1请求后,再发起/test2请求,此时get_flashed_messages()获取到的是个空列表[]
data = get_flashed_messages()
return '获取的信息:%s'%data
原因:
源码中第一次flashes是从session中获取,并且存到了_request_ctx_stack.top.flashes = flashes
中,再次在该请求中调用方法时直接从flashes中可以获取。所以可以在同一请求中多次调用get_flashed_messages方法
而在第一次请求中执行了 session.pop("_flashes")。所以在第二次请求中便取不到flashes了。所以不能在第二次请求中获取flash值
flashes = _request_ctx_stack.top.flashes
if flashes is None:
_request_ctx_stack.top.flashes = flashes = (
session.pop("_flashes") if "_flashes" in session else []
)
return flashes