上篇文章我们学习了Flask框架——Session与Cookie,这篇文章我们来学习Flask框架——flask-caching缓存。
我们访问网页时,一般都需要加载网页中的很多数据资源,例如我们访问京东或淘宝首页,如下图所示:
每次访问都需要加载上面的数据资源,假如每次都是从web服务器中加载这些数据资源,而这些数据资源比较大的话,服务器可能响应这些资源需要比较久的时间,那么我们在短时间内访问这些网页时,访问效率会很低,用户体验会很差。
为了提高web应用访问效率,减少web服务器的响应时间,我们可以在需要经常访问的网页或某个数据模块中添加缓存,在一定时间内直接在缓存中获取数据资源而不是每次都要在web服务器中获取数据资源。
Redis是一个基于内存的、高效的键值型非关系型数据库,存取效率极高,而且支持多种数据存储结构,使用起来也非常简单。所以我们使用Redis非关系型数据库作为我们缓存数据的存放位置。执行如下代码安装Redis和flask-caching:
pip install flask-caching
pip install redis
注意:除了通过pip install redis安装redis,还需要在根据运行环境在windows和服务器中安装Redis在路径中找到:redis-cli.exe文件并双击该文件启动redis服务。
我们来了解一下flask-caching支持的缓存类型:
flask-caching内置的缓存类型CACHE_TYPE有:NullCache、SimpleCache、FileSystemCache、RedisCache、RedisSentinelCache、RedisClusterCache、UWSGICache、MemcachedCache、SASLMemcachedCache和SpreadSASLMemcachedCache(在Flask-Caching2.0中删除)。
其中:
NullCache:无缓存,其配置参数可以有:
SimpleCache:使用本地python字典进行存储,非线程安全,其配置参数可以有:
FileSystemCache:使用文件系统来存储缓存的值,其配置参数可以有:
RedisCache:使用Redis作为缓存后端,其配置参数可以有:
RedisSentinelCache:使用Redis哨兵模型缓存,其配置参数可以有:
RedisClusterCache:使用Redis自动分区缓存,其配置参数可以有:
MemcachedCache:使用memcached服务器作为缓存后端,支持pylibmc或memcache或Google应用程序引擎memcache库,其配置参数可以有:
注意:Flask-Caching不会将额外的配置选项传递给memcached后端,要向这些缓存添加其他配置。
SASLMemcachedCache:启用SASL的memcached服务器作为缓存后端,其配置参数可以有:
UWSGICache:使用uwsgi服务器作为缓存,其配置参数可以有:
注意:该UWSGICache没有维护也没有测试,不建议使用。
这里我们的缓存类型为RedisCache:
from flask import Flask
from flask_caching import Cache
#配置RedisCache缓存类型参数值,我们使用本地的redis,没有密码
config={
'CACHE_TYPE':'redis', #使用redis作为缓存
'CACHE_REDIS_HOST':'127.0.0.1', #redis地址
'CACHE_REDIS_PORT':6379 #redis端口号
}
app = Flask(__name__)
#初始化缓存
cache=Cache(app=app,config=config) #创建Cache对象
#或使用init_app()初始化缓存
#cache=Cache() #创建Cache对象
#cache.init_app(app=app,config=config)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
我们可以根据需要可以将CACHE_REDIS_HOST换为服务器的地址。
Cache对象的主要方法有:
#装饰器,装饰无参数函数,缓存该函数
@cache.cached(timeout=None,key_prefix=None,unless=None,forced_update=None,query_string=False)
timeout为超时时间;
可选参数有:
#装饰器,装饰有参数函数,缓存该函数
@cache.memoize(timeout=None,make_name=None,unless=None,forced_update=None,query_string=False)
与cache.cached()方法类似,区别为cache.memoize有make_name,其作用是设置函数的标志,如果没有就使用装饰的函数。
我们可以使用缓存缓存视图函数、其他函数、对象(键值对)。
视图函数代码如下所示:
@app.route('/view')
@cache.cached(timeout=30) #设置超时时间
def view():
time.sleep(2) #模拟数据加载时间
return '视图函数缓存'
为了能更好地体现效果,我们通过设置休眠时间来模拟数据加载时间,启动Flask项目,浏览器访问http://127.0.0.1:5000/view,可以发现网页需要过了两秒才显示内容,在30秒内,我们再次访问该网页就会秒显示内容,过了30秒后,再次访问网页,又需要过两秒才显示内容。
在缓存其他函数时,需要使用关键字key_prefix指定缓存哪个函数。代码如下所示:
@cache.cached(timeout=50, key_prefix='get_list')
def timesleep():
time.sleep(2)
return '缓存其他无参函数'
@app.route('/others')
def others():
return timesleep()
启动flask项目后,访问http://127.0.0.1:5000/others结果和刚才演示缓存视图函数一样。
在缓存对象中,我们可以使用以下代码来设置、获取、删除缓存对象:
#设置
cache.set(key,value,timeout=None) #设置一个缓存对象
cache.set_many([(key,value),(key,value),...,(key,value)],timeout=None) #设置多个缓存对象
#获取
cache.get(key) #获取一个缓存对象
cache.get_many(key1,key2,....) #获取多个缓存对象
#删除
cache.get.delete(key) #删除一个缓存对象
cache_delete_many(key1,key2,...) #删除多个缓存对象
cache.clear() #删除所有缓存对象
为了方便演示,我们简单地操作缓存对象:
@app.route('/object')
def object():
cache.set('name', '小明', timeout=30) #设置键为name,value为小明,超时时间为30秒的缓存对象
print(cache.get('name')) #打印键为name的缓存对象值
cache.set_many([('name1', '小明'), ('name2', '老王')],timeout=30) #设置多个缓存对象
print(cache.get_many("name1", "name2")) #打印多个缓存对象值
print(cache.delete("name")) #删除键为name的缓存对象
print(cache.delete_many("name1", "name2")) #删除多个缓存对象
return '缓存对象'
启动flask项目,访问http://127.0.0.1:5000/object,在pycharm中终端,如下图所示:
好了,关于Flask框架——flask-caching缓存就讲到这里了,感谢观看,下篇文章我们学习Flask框架——消息闪现。
我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:
尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我想开始使用“Sinatra”框架进行编码,但我找不到该框架的“MVC”模式。是“MVC-Sinatra”模式或框架吗? 最佳答案 您可能想查看Padrino这是一个围绕Sinatra构建的框架,可为您的项目提供更“类似Rails”的感觉,但没有那么多隐藏的魔法。这是使用Sinatra可以做什么的一个很好的例子。虽然如果您需要开始使用这很好,但我个人建议您将它用作学习工具,以对您来说最有意义的方式使用Sinatra构建您自己的应用程序。写一些测试/期望,写一些代码,通过测试-重复:)至于ORM,你还应该结帐Sequel其中(imho
有什么方法可以告诉Rails3在给定的Controller中缓存所有页面,而不必在调用caches_page时列出所有页面?我尝试了caches_page:all,但它不起作用。 最佳答案 有点像实现的错误,但我刚刚尝试过它并且它适用于Rails3.0.6:caches_page:except=>[] 关于ruby-caches_page:all,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/que
我正在尝试升级到Rails4beta1,但遇到了一些问题。简而言之,这就是我的应用程序Controller的样子。classApplicationControllercaches_action在Rails4中移到了它自己的gem中,因此包含gem应该可以解决问题。gem"actionpack-action_caching",github:"rails/actionpack-action_caching"但是当我运行我的请求规范或在浏览器中访问该应用程序时,我收到此错误。app/controllers/application_controller.rb:3:in`':undefinedm
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我一直在Rails上做两个项目,它们运行良好,但在这个过程中重新发明了轮子,自来水(和热水)和止痛药,正如我随后了解到的那样,这些已经存在于框架中。那么基本上,正确了解框架中所有智能部分的最佳方法是什么,这将节省时间而不是自己构建已经实现的功能?从第1页开始阅读文档?是否有公开所有内容的特定示例应用程序?一个特定的开源项目?所有的rails交通?还是完全
当我尝试进行bundle安装时,我的gem_path和gem_home指向/usr/local/rvm/gems/我没有写入权限,并且由于权限无效而失败。因此,我已将两个路径都更改为我具有写入权限的本地目录。这样做时,我进行了bundle安装,我得到:bruno@test6:~$bundleinstallFetchinggemmetadatafromhttps://rubygems.org/.........Fetchinggemmetadatafromhttps://rubygems.org/..Bundler::GemspecError:Couldnotreadgemat/afs/
在rails开发环境中,cache_classes是关闭的,所以你可以修改app/下的代码,不用重启服务器就可以看到变化。不过,在所有环境中,中间件只会创建一次。所以如果我有这样的中间件:classMyMiddlewaredefinitialize(app)@app=appenddefcall(env)env['model']=MyModel.firstendend我在config/environments/development.rb中执行此操作:config.cache_classes=false#thedefaultfordevelopmentconfig.middleware.