博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用 Flask 来写个轻博客 (27) — 使用 Flask-Cache 实现网页缓存加速
阅读量:5905 次
发布时间:2019-06-19

本文共 4024 字,大约阅读时间需要 13 分钟。

Blog 项目源码:

目录

前文列表

扩展阅读

Flask-Cache

网页的加载时间决定了你的网站是否能够受到用户的欢迎, 现在为止我们 blog 应用模板的每次渲染都会查询数据库, 这是不合理的. 对一些数据不被经常改变的页面我们应该引入缓存的机制来减少对数据库的访问.

Flask-Cache 能够让我们把视图函数返回的结果缓存下来, 以后再次渲染时, 只需要从缓存中取出这些结果就可以了, 无须重复的渲染.

  • 安装
pip install Flask-Cachepip freeze > requirement.txt

应用 Flask-Cache 实现视图函数缓存

  • 初始化
    vim jmilkfansblog/extensions.py
from flask.ext.cache import Cache...#### Create the Flask-Cache's instancecache = Cache()
  • 将 cache 对象注册到 app 对象中
    vim jmilkfansblog/__init__.py
from jmilkfansblog.extensions import cache...def create_app(object_name):    """Create the app instance via `Factory Method`"""...    #### Init the Flask-Cache via app object    cache.init_app(app)
  • 配置 Cache 类型
class DevConfig(Config):    """Development config class."""...    #### Flask-Cache's config    CACHE_TYPE = 'simple'

Flask-Cache 定义缓存的方式就是为你需要缓存的函数加上缓存装饰器, 这样的装饰器由多种类型, 对应装饰在不同的函数或视图函数中.

缓存无参数的普通函数

vim jmilkfansblog/controllers/blog.py

@cache.cached(timeout=7200, key_prefix='sidebar_data')def sidebar_data():    """Set the sidebar function."""    # Get post of recent    recent = db.session.query(Post).order_by(            Post.publish_date.desc()        ).limit(5).all()    # Get the tags and sort by count of posts.    top_tags = db.session.query(            Tag, func.count(posts_tags.c.post_id).label('total')        ).join(            posts_tags        ).group_by(Tag).order_by('total DESC').limit(5).all()    return recent, top_tags

NOTE 1: 装饰器 @ cache.cached() 的形参数 key_prefix 是必须的, 并且传入的值是唯一的, 这样 Flask-Cache 才能够正确的返回该函数缓存的值.

NOTE 2: 该函数被缓存的时间设定为 2 小时, 这是因为该函数返回的值不被经常改变, 而且就算是被改变了也不会对整体页面的显示有大的影响.

缓存带参数的普通函数

装饰器 cache.cached() 不会考虑到参数的问题, 如果函数在接收到不同的实参后还返回相同结果的话, 这明显是不科学的. 为了解决这个问题, 我们使用 @cache.memoize() 装饰器来定义.

vim jmilkfansblog/models.py

@staticmethod    @cache.memoize(60)    def verify_auth_token(token):        """Validate the token whether is night."""        serializer = Serializer(            current_app.config['SECRET_KEY'])        try:            # serializer object already has tokens in itself and wait for             # compare with token from HTTP Request /api/posts Method `POST`.            data = serializer.loads(token)        except SignatureExpired:            return None        except BadSignature:            return None        user = User.query.filter_by(id=data['id']).first()        return user

NOTE 1: 装饰器 @cache.memoize() 不仅仅会缓存运行的结果, 还缓存调用时的参数, 所以在函数接受到相同的参数时, 就会将缓存中该参数对应的结果返回.

NOTE 2: @cache.momoize() 非常不适用于返回结果依赖全局变量或依赖数据库查询的函数, 因为在这很容易导致数据竞态, 即输入了相同的参数, 可能会返回不同的结果. 最适合被缓存的函数是纯函数(在传入的参数相同的情况下会输出相同的结果)

缓存无动态参数的视图函数

# Use the Blueprint object to set the Route URL# Register the view function into blueprint@blog_blueprint.route('/')@blog_blueprint.route('/
')@cache.cached(timeout=60)def home(page=1): """View function for home page""" posts = Post.query.order_by( Post.publish_date.desc() ).paginate(page, 10) recent, top_tags = sidebar_data() return render_template('home.html', posts=posts, recent=recent, top_tags=top_tags)

NOTE 1: 这里仍然是使用装饰器 @cache.cached(), 但却不必需要指定 key_prefix 形参.

NOTE 2: timeout 表示该视图函数返回的结果将会被缓存的时长.

缓存带动态参数的视图函数

因为该类型视图函数的参数 post_id 是被动态解析成为 URL(/post/<string:post_id>) 的, 所以并不是每一次调用都会返回相同的结果, 这样就需要我们进一步的确认, 只有在确定两次不同请求的都是同一个目标(即 URL)时, 才会将缓存返回, 否则创建一个新的缓存.

def make_cache_key(*args, **kwargs):    """Dynamic creation the request url."""    path = request.path    args = str(hash(frozenset(request.args.items())))    return (path + args).encode('utf-8')...@blog_blueprint.route('/post/
', methods=('GET', 'POST'))@cache.cached(timeout=60, key_prefix=make_cache_key)def post(post_id): """View function for post page""" # Form object: `Comment` form = CommentForm()...

NOTE 1: 这里我们仍然使用了 key_prefix 参数来进行定位, 而且该形参除了可以接受 String 类型对象之后, 也可以接收一个函数.

NOTE 2: 函数 make_cache_key() 会动态的生成一个唯一的缓存键, 用于确定这一次请求的 URL 是否存在缓存, 如果存在则返回, 如果不存在则新建. 所以在该函数中我们使用了请求 path + hash 字符串结合而成的唯一字符串作为缓存键.

转载于:https://www.cnblogs.com/jmilkfan-fanguiju/p/10589852.html

你可能感兴趣的文章
hyper-v 无线网连接
查看>>
Python3.7.1学习(六)RabbitMQ在Windows环境下的安装
查看>>
Windows下memcached的安装配置
查看>>
ubuntu: firefox+flashplay
查看>>
web.xml 中CharacterEncodingFilter类的学习
查看>>
贪吃蛇逻辑代码
查看>>
ASP.NET视频教程 手把手教你做企业论坛网站 视频教程
查看>>
[LeetCode] Meeting Rooms II
查看>>
从Swift学习iOS开发的路线指引
查看>>
Scribes:小型文本编辑器,支持远程编辑
查看>>
ssh 安装笔记
查看>>
3-继承
查看>>
海归千千万 为何再无钱学森
查看>>
vue2.0 仿手机新闻站(六)详情页制作
查看>>
JSP----九大内置对象
查看>>
Java中HashMap详解
查看>>
delphi基本语法
查看>>
260. Single Number III
查看>>
Hadoop生态圈-Kafka的完全分布式部署
查看>>
[MODx] Build a CMP (Custom manager page) using MIGX in MODX 2.3 -- 1
查看>>