flask扩展缓存

Erick-LONG Erick-LONG     2022-09-05     147

关键词:

如果同一个请求会被多次调用,每次调用都会消耗很多资源,并且每次返回的内容都相同,就该使用缓存了

自定义缓存装饰器

在使用Flask-Cache扩展实现缓存功能之前,我们先来自己写个视图缓存装饰器,方便我们来理解视图缓存的实现。首先,我们要有一个缓存,Werkzeug框架中的提供了一个简单的缓存对象SimpleCache,它是将缓存项存放在Python解释器的内存中,我们可以用下面的代码获取SimpleCache的缓存对象:

from werkzeug.contrib.cache import SimpleCache
cache = SimpleCache()

如果你要使用第三方的缓存服务器,比如Memcached,Werkzeug框架也提供了它的wrapper:

from werkzeug.contrib.cache import MemcachedCache
cache = MemcachedCache([127.0.0.1:11211])

此后就可以使用cache对象的”set(key, value, timeout)”和”get(key)”方法来存取缓存项了。注意”set()”方法的第三个参数”timeout”是缓存过期时间,默认为0,也就是永不过期。

def cached(timeout=5 * 60, key=view_%s):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            cache_key = key % request.path
            value = cache.get(cache_key)
            if value is None:
                value = f(*args, **kwargs)
                cache.set(cache_key, value, timeout=timeout)
            return value
        return decorated_function
    return decorator

装饰器的两个参数分别是缓存的过期时间,默认是5分钟;缓存项键值的前缀,默认是”view_”。然后我们写个视图,并使用此装饰器:

@app.route(/hello)
@app.route(/hello/<name>)
@cached()
def hello(name=None):
    print view hello called
    return render_template(hello.html, name=name)

我们试下访问这个视图,对于同样的URL地址,第一次访问时,控制台上会有”view called”输出,第二次就不会了。如果过5分钟后访问,”view called”才会再次输出。

安装和启用Flask-Cache

了解了缓存装饰器的内部实现,我们就可以开始介绍Flask的缓存扩展,Flask-Cache。首先使用pip将其安装上:

pip install flask-cache

然后创建一个Flask-Cache的实例:

from flask import Flask
from flask_cache import Cache
 
app = Flask(__name__)
cache = Cache(app, config={CACHE_TYPE: simple})

上例中,我们使用了’simple’类型缓存,其内部实现就是Werkzeug中的SimpleCache。我们也可以使用第三方的缓存服务器,比如Redis,代码如下:

cache = Cache(app, config={CACHE_TYPE: redis,          # Use Redis
                           CACHE_REDIS_HOST: abc.com,  # Host, default ‘localhost‘
                           CACHE_REDIS_PORT: 6379,       # Port, default 6379
                           CACHE_REDIS_PASSWORD: 111,  # Password
                           CACHE_REDIS_DB: 2}            # DB, default 0

其内部实现是”werkzeug.contrib.cache”包下的”RedisCache”,所以说Flask-Cache就是基于Werkzeug框架的Cache库实现的。

应用中使用缓存

同自定义缓存装饰器一样,我们可以用cache对象的”cached()”方法来装饰视图函数,以达到缓存视图的目的:

@app.route(/hello)
@app.route(/hello/<name>)
@cache.cached(timeout=300, key_prefix=view_%s, unless=None)
def hello(name=None):
    print view hello called
    return render_template(hello.html, name=name)

“cache.cached()”装饰器有三个参数:

  • timeout:过期时间,默认为None,即永不过期
  • key_prefix:缓存项键值的前缀,默认为”view/%s”
  • unless:回调函数,当其返回True时,缓存不起作用。默认为None,即缓存有效

除了装饰视图函数,”cache.cached()”装饰器也可以用来装饰普通函数:

@cache.cached(timeout=50, key_prefix=get_list)
def get_list():
    print method get_list called
    return [a,b,c,d,e]
 
@app.route(/list)
def list():
    return , . join(get_list())

我们访问”/list”地址时,第一次控制台上会有”method called”输出,第二次就不会了,说明缓存起效了。装饰普通函数时必须指定明确的”key_prefix”参数,因为它不像视图函数,可以使用请求路径”request.path”作为缓存项的键值。如果函数带参数,对于不同的参数调用,都会使用同一缓存项,即返回结果一样。Flask-Cache还提供了另一个装饰器方法”cache.memoize()”,它与”cache.cached()”的区别就是它会将函数的参数也放在缓存项的键值中:

@cache.memoize(timeout=50)
def create_list(num):
    print method create_list called
    l = []
    for i in range(num):
        l.append(str(i))
    return l
 
@app.route(/list/<int:num>)
def list(num):
    return , .join(create_list(num))

我们再次访问”/list”地址,对于不同的参数,”method called”会一直在控制台上打印出,而对于相同的参数,第二次就不会打印了。所以对于带参数的函数,你要使用”cache.memoize()”装饰器,而对于不带参数的函数,它同”cache.cached()”基本上一样。”cache.memoize()”装饰器也有三个参数,”timeout”和”unless”参数同”cache.cached()”一样,就是第二个参数”make_name”比较特别。它是一个回调函数,传入的是被装饰的函数名,返回是一个字符串,会被作为缓存项键值的一部分,如果不设,就直接使用函数名。

删除缓存

对于普通缓存,你可以使用”delete()”方法来删除缓存项,而对于”memoize”缓存,你需要使用”delete_memoized”方法。如果想清除所有缓存,可以使用”clear()”方法。

cache.delete(get_list)                     # 删除‘get_list‘缓存项
cache.delete_many(get_list, view_hello)  # 同时删除‘get_list‘和‘view_hello‘缓存项
cache.delete_memoized(create_list, 5)      # 删除调用‘create_list‘函数并且参数为5的缓存项
cache.clear()                                # 清理所有缓存

Jinja2模板中使用缓存

其实在Jinja2模板中,我们还可以使用”{% cache %}”语句来缓存模板代码块:

{% cache 50, ‘temp‘ %}
<p>This is under cache</p>
{% endcache %}

这样”{% cache %}”和”{% endcache %}”语句中所包括的内容就会被缓存起来。”{% cache %}”语句的第一个参数是”timeout”过期时间,默认为永不过期;第二个参数指定了缓存项的键值,如果不设,键值就是”模板文件路径”+”缓存块的第一行”。上例中,我们设了键值是”temp”,然后在代码中,我们可以这样获取缓存项实际的键值:

from flask_cache import make_template_fragment_key
key = make_template_fragment_key(‘temp‘)

打印出来看看,你会发现实际的键值其实是”_template_fragment_cache_temp”。如果你要删除该缓存项,记得要传入实际的键值,而不是模板上定义的’temp’。

flask简单使用

...n、Form、缓存、信号、序列化....2Flask:无socket、中间件(扩展)、路由系统、视图(CBV)、第三方模板(jinja2)、cookie、Ses 查看详情

flask常用扩展介绍系列文章索引

这篇文章包含常用扩展介绍系列文章的索引目录。关于扩展的基础知识可以阅读《Flask扩展的配置、初始化与管理》了解。*扩展列表按照写作时间排序Flask-WTF文章:关于Flask表单,我所知道的一切GitHub主页:lepture/flask-wtf文档:Fl... 查看详情

Flask 默认 http 标头 - 缓存等

】Flask默认http标头-缓存等【英文标题】:Flaskdefaulthttpheaders-Cachingandmore【发布时间】:2021-02-0422:50:08【问题描述】:我正在询问Flask并且想知道缓存控制之类的默认值是什么。我找不到有关任何HTTP标头的信息。也许我弄错了,是... 查看详情

flask-uploads扩展的使用笔记

涉及的flask扩展flask-uploadsflask的一个文件上传扩展,提供了UploadSet这个概念flask-wtf(中文)很强大的表单的扩展flask-bootstrapbootstrap的flask扩展,结合模版使用,此处用到quick_form功能 fromflaskimportFlask,render_templatefromflask_uploadsimportUpl 查看详情

flask的扩展

1.Flask-Script,为Flask程序提供了一个命令行解析器:(venv)$pipinstallflask-script2.Bootstrap(http://getbootstrap.com/)是客户端框架,详情看连接集成Flask-Bootstrap的命令,(venv)$pipinstallflask-bootstrap3.Flask-Moment扩展,能把moment.js(在浏览器中 查看详情

flask扩展--flask-mail

...用在Flask程序中发送电子邮件,但包装了smtplib的Flask-Mail扩展能更好的和Flask集成。1.安装Flask-Mail1.1使用pip安装pipinstallflask-mail1.2下载源码安装gitclonehttps://github.com/mattupstate/flask-mail.gitcd 查看详情

flask插件系列之flask_caching缓存(代码片段)

前言为了尽量减少缓存穿透,同时减少web的响应时间,我们可以针对那些需要一定时间才能获取结果的函数和那些不需要频繁更新的视图函数提供缓存服务,可以在一定的时间内直接返回结果而不是每次都需要计算或者从数据库... 查看详情

flask扩展http认证

...赖Cookie及Session来保存用户信息,自然也无法使用Flask-Login扩展来实现用户认证。所以这里,我们就要介绍另一个扩展,Flask-HTTPAuth。pipinstallflask-httpauth接下来创建扩展对象实例:fromflaskimportFlaskfromflask_httpauthimportHTTPBasicAuthapp=F 查看详情

2.6flask扩展

Flask被设计为可扩展形式,故而没有提供一些重要的功能,例如数据库和用户认证,所以开发者可以自由选择最适合程序的包,或者按需求自行开发。社区成员开发了大量不同用途的扩展,如果这还不能满足需求,你还可使用所... 查看详情

flask-restful扩展

...已经相当简单了Flask还有更简便的方法,就是其Flask-RESTful扩展。首先,我们来安装这个扩展:pipinstallFlask-RESTful安装完后,你就可以在代码中导入该扩展包fromflaskimportFlask,requestfromflask_restfu 查看详情

flask扩展flask-pymongo

安装pipinstall Flask-PyMongo初始化Pymongo实例fromflaskimportFlaskfromflask.ext.pymongoimportPyMongoapp=Flask(__name__)app.config.update(MONGO_HOST=‘localhost‘,MONGO_PORT=27017,MONGO_USERNAME=‘bjhee‘,MON 查看详情

flask之邮件扩展(代码片段)

...过程中,很多应用程序都需要通过邮件提醒用户,Flask的扩展包Flask-Mail通过包装了Python内置的smtplib包,可以用在Flask程序中发送邮件。Flask-Mail连接到简单邮件协议(SimpleMailTransferProtocol,SMTP)服务器,并把邮件交给服务器发送。... 查看详情

flask扩展

...复杂的页面怎么办?写表单怎么办?发邮件呢?......flask扩展:发送邮件链接:http://pythonhosted.org/Fla 查看详情

1.flask基础(代码片段)

...框架,内置了:路由/视图/模板(jinja2)/cookie/session/中间件.可扩展强,第三方组件非常多,例如:wtforms/flask-session/flask-sqlalchemy.django,是一个重武器,django内置了很多功能方便我们使用,例如:admin/orm/模板/form/modelform/session/cookie/中间件/路由/... 查看详情

flask扩展--flask-script

Flask-Scropt插件:为在Flask里编写额外的脚本提供了支持。这包括运行一个开发服务器,一个定制的Python命令行,用于执行初始化数据库、定时任务和其他属于web应用之外的命令行任务的脚本。一.使用Flask-Script支持命令行选项1.安装... 查看详情

使用flask-mail扩展发送邮件(代码片段)

使用flask-mail扩展发送电子邮件在我们开发完web系统后,一些特定的事件发生时,系统要自动发送相关邮件至管理员,运维人员和其他相关人员。python标准库中的smtplib包也可以用在Flask程序中发送邮,但包装了smtplib的flask-mail扩展... 查看详情

flask-uploads扩展的使用

参考:http://www.cnblogs.com/himir/p/5940705.htmlhttps://zhuanlan.zhihu.com/p/24423891flask-uploads    flask的一个文件上传扩展, 提供了UploadSet这个概念    flask-wtf(中文)  查看详情

flask扩展mail

安装pipinstallflask-mailfromflaskimportFlaskfromflask_mailimportMail,Messageapp=Flask(__name__)app.config.update(MAIL_SERVER=‘smtp.example.com‘,MAIL_USERNAME=‘bjhee‘,MAIL_PASSWORD=‘example‘)mail=Mail(ap 查看详情