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

flask 源码专题(十):flash源码研究的更多相关文章

  1. flask 源码专题(五):SqlAlchemy 中操作数据库时session和scoped_session的区别

    1原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalc ...

  2. flask 源码专题(二):请求上下文与全文上下文

    源码解析 0. 请求入口 if __name__ == '__main__': app.run() def run(self, host=None, port=None, debug=None, lo ...

  3. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

  4. OpenJDK源码研究笔记(十):枚举的高级用法,枚举实现接口,竟是别有洞天

    在研究OpenJDK,Java编译器javac源码的过程中,发现以下代码. 顿时发现枚举类竟然也有如此"高端大气上档次"的用法. 沙场点兵(用法源码) com.sun.tools. ...

  5. OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa

    元数据最本质.最抽象的定义为:data about data (关于数据的数据).它是一种广泛存在的现象,在许多领域有其具体的定义和应用. JDBC中的元数据,有数据库元数据(DatabaseMeta ...

  6. Flask框架(五) —— session源码分析

    Flask框架(五) —— session源码分析 目录 session源码分析 1.请求来了,执行__call__方法 2.__call__方法 3.调用__call__方法 3.1.ctx = s ...

  7. netty源码分析(十八)Netty底层架构系统总结与应用实践

    一个EventLoopGroup当中会包含一个或多个EventLoop. 一个EventLoop在它的整个生命周期当中都只会与唯一一个Thread进行绑定. 所有由EventLoop所处理的各种I/O ...

  8. mybatis源码专题(2)--------一起来看下使用mybatis框架的insert语句的源码执行流程吧

    本文是作者原创,版权归作者所有.若要转载,请注明出处.本文以简单的insert语句为例 1.mybatis的底层是jdbc操作,我们先来回顾一下insert语句的执行流程,如下 执行完后,我们看下数据 ...

  9. 【 js 基础 】【 源码学习 】backbone 源码阅读(三)浅谈 REST 和 CRUD

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...

随机推荐

  1. Thread基础-创建线程的方式

    Java线程创建的几种简单方式 1. extends Thread类 public class ThreadDemo extends Thread{ @Override public void run ...

  2. 分享一个springboot脚手架

    项目介绍 在我们开发项目的时候各个项目之间总有一些可共用的代码或者配置,如果我们每新建一个项目就把代码复制粘贴再修改就显得很没有必要.于是我就做了一个 poseidon-boot-starter 该项 ...

  3. easypoi 读取 Excel 简单应用

    背景 在做接口测试的时候,经常会使用 Excel 来存储对应的接口信息和用例信息,为了方便程序的读取,引入easypoi 工具来读取 Excel 内容.easypoi 比起 poi 使用更加的方便,代 ...

  4. 0.1---selenium+java自动化测试进阶01---PageObject设计模式

    一.PageObject设计模式   1.简介 PageObject设计模式,又称页面对象模式,是使用Selenium的广大同行最为公认的一种设计模式.在设计测试时,把元素和方法按照页面抽象出来,分离 ...

  5. 在IntelliJ IDEA中注释使用的说明

    /** * @author 标明该类模块的开发作者 * @version 标明该类模块的版本 * @see 参开转向,也就是相关的主题 * @param 对方法中的某些参数进行说明 * @return ...

  6. Dubbo——服务引用

    文章目录 引言 正文 服务订阅 Invoker的创建 单注册中心的Invoker创建 Dubbo直连的Invoker创建 创建代理类 引言 上一篇我们分析了服务发布的原理,可以看到默认是创建了一个Ne ...

  7. ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换

    /*ca33a_demo_c++33_CppPrimer_新旧代码的兼容_txwtech旧代码:数组和c风格字符串新代码:vector和string相互转换:c风格字符串<- ->stri ...

  8. winXP vc6行号显示插件-VC6LineNumberAddin方法-可用-无需注册

    1.VC6LineNumberAddin 修改日期是2008.6.3可用,其它需要注册码 http://codefish.googlecode.com/files/VC%E6%98%BE%E7%A4% ...

  9. ConcurrentHashMap源码解析-Java7

    目录 一.ConcurrentHashMap的模型图 二.源码分析-类定义 2.1 极简ConcurrentHashMap定义 2.2 Segment内部类 2.3 HashEntry内部类 2.4 ...

  10. 这一次搞懂Spring Web零xml配置原理以及父子容器关系

    前言 在使用Spring和SpringMVC的老版本进行开发时,我们需要配置很多的xml文件,非常的繁琐,总是让用户自行选择配置也是非常不好的.基于约定大于配置的规定,Spring提供了很多注解帮助我 ...