flask-cache 缓存Jinja2模板之源码解读
来源:互联网 发布:五星宏辉软件 编辑:程序博客网 时间:2024/05/16 19:23
注:缓存jinja2模板的代码详见:flask-cache缓存的示例代码
1.缓存模板的关键代码:
模板cached_blueprint_app/templates/zen.html
定义缓存参数:
{% cache timeout %} #timeout是缓存超期时间{% endcache %} # 缓存区域结束标记
文件cached_blueprint_app/app.py中实例一个当前应用的缓存:
app.cache = Cache(app)
2.源码解读
2.1 Cache类初始化的关键代码如下:
class Cache: def __init__(self,app=None,with_jinja2_ext=True,config=None): if app is not None: self.init_app(app, config) #<1> def init_app(self, app, config=None): if self.with_jinja2_ext: from .jinja2ext import CacheExtension, JINJA_CACHE_ATTR_NAME #<2> setattr(app.jinja_env, JINJA_CACHE_ATTR_NAME, self) #<3> app.jinja_env.add_extension(CacheExtension) #<4> def add_extension(self, extension): #<5> self.extensions.update(load_extensions(self, [extension])) #<6>
上边的代码说明:
<1>初始化当前app缓存操作.
<2>CacheExtension jinja2模板的缓存扩展,实现模板变量缓存的核心功能.
<3>将cache实例存储到jinja_env属性中,方便后边存储缓存时,从环境中取出cache对象.
<4>将CacheExtension加入到jinja环境的扩展中.
<5>当环境创建之后,加入扩展
<6>使用load_extensions的返回结果,来更新扩展程序的字典,实现注册缓存实例到特定环境的功能
2.2 load_extension函数实现CacheExtension的实例化
def load_extensions(environment, extensions): #<7> result[extension.identifier]=extension(environment) #<8>
<7>实现从扩展列表中加载扩展,并与当前的环境绑定,返回app环境的实例(一个字典形式)
<8>result 是返回值,是以扩展的标识符为key,以扩展实例为value的字典形式
<8> 扩展标识符是扩展在注册时生成的(ExtensionRegistry类__new__
方法实现)
2.3 缓存核心类CacheExtension鸟瞰
UML图如下:
说明:
1) CacheExtension的父类Extension实现扩展的基本接口的定义。
2) Extension的父类ExtensionRegistry 实现扩展注册分配标识符的功能。
CacheExtension的功能很简单简单主要有一个字段和两个方法组成:
(1) 字段tags=set([‘cache’])
用于解析匹配,当检测到模板中的tag与CacheExtension的tag字段匹配时,表示当前模板文件有变量需要缓存。
(2) 方法CacheExtension._cache
进行实际的解析操作。当检测到实际的缓存结束的关键字endcache时,会获取整个模板文件的主要内容(body),随后调用内部方法_cache将变量存入缓存中。
def _cache(self, timeout, fragment_name, vary_on, caller): try: cache = getattr(self.environment, JINJA_CACHE_ATTR_NAME) #<9> except AttributeError as e: raise e key = make_template_fragment_key(fragment_name, vary_on=vary_on) #<10> rv = cache.get(key) if rv is None: rv = caller() cache.set(key, rv, timeout) #<11> return rvdef make_template_fragment_key(fragment_name, vary_on=[]): """ Make a cache key for a specific fragment name """ if vary_on: fragment_name = "%s_" % fragment_name return TEMPLATE_FRAGMENT_KEY_TEMPLATE % (fragment_name, "_".join(vary_on)) #<10>
<9> 从jinja环境中取出cache对象
<10> 生成模板的键,键的格式是前缀+完整路径名的形式(如果vary_on不存在)
<11> 将模板中的值存入缓存
附注一个示例的body内容:
Body = [Output(nodes=[TemplateData(data='\n<h3> Random Zen of Python </h3>\n<strong>'),Call(node=Name(name='get_random_quote', ctx='load'), args=[], TemplateData(data='</strong>\n')])]
解释一下:
TemplateData里边模板的具体内容。
Call里边是模板调用的方法get_random_quote
ExtensionRegistry 类的代码很简单,只有一个创建对象的方法。实现了两个功能:
1创建类2.为类创建唯一的表示符
class ExtensionRegistry(type): """Gives the extension an unique identifier.""" def __new__(cls, name, bases, d): rv = type.__new__(cls, name, bases, d) rv.identifier = rv.__module__ + '.' + rv.__name__ #标识符采用包名+'.'+类名 return rv
在对jinja缓存时,CacheExtension的扩展标识符(identifier)是:flask_cache.jinja2ext.CacheExtension。这样可以区分不同包下相同类的标识符唯一的情况。
3.缓存模板的完整函数调用图:
- flask-cache 缓存Jinja2模板之源码解读
- Flask Jinja2模板
- flask-cache 之缓存cache实现原理
- Flask web 开发 Jinja2 模板
- Flask中的Jinja2模板使用
- Flask-Jinja2模板学习总结
- Python 之 jinja2模板
- Flask模板引擎——Jinja2
- Python学习:Flask框架和jinja2模板
- Flask入门(二)Jinja2 模板
- Flask(Jinja2) 服务端模板注入漏洞
- flask jinja2
- flask--jinja2
- Flask学习总结笔记(4)-- Jinja2模板引擎之二
- Flask笔记(2)--flask的jinja2模板引擎
- 解读flask框架,flask源码解读
- 使用 Flask-Cache 缓存给Flask提速
- Python Flask Web 第四课 —— 模板引擎Jinja2
- HBUOJ. 破译邮件
- Qt配置pro文件
- MySQL 教程「事务(下)」
- HTML 相对定位和绝对定位 放置位置
- linux下GNU、G++编辑器的安装及基本使用
- flask-cache 缓存Jinja2模板之源码解读
- Java选择排序、冒泡排序、直接插入排序与二分查找
- 【java】-- 调戏Integer 包装与解包装
- 条款3:使容器里对象的拷贝操作轻量而正确
- umask使用方法
- jQuery第六章插件
- python学习总结---while循环
- Bailian3179 最长单词【字符串】
- js函数重载