如何优雅地改进Django中的模板碎片缓存详解


Posted in Python onJuly 04, 2018

前言

本文主页给大家介绍了关于如何改进Django中模板碎片缓存的相关内容,关于Django模板碎片缓存大家可以先看看这篇文章,下面话不多说了,来一起看看详细的介绍吧

起步

Django 的缓存体系提供了模板片段缓存:

{% load cache %}
{% cache 500 sidebar %}
 .. sidebar ..
{% endcache %}

但使用这个模板缓存还是需要每次都把需要的变量 sidebar 传给模板,不然当缓存过期时碎片是空白的。于是就需要的视图中获取这些数据:

def test_view(request):
 # code...
 sidebar = get_data()
 return render(reqeust, 'test_view.html', {'sidebar': sidebar})

如果这个数据获取的过程比较耗时,那么这个碎片缓存形同虚设。

低级缓存

使用低级缓存能解决数据获取耗时问题:

from django.core.cache import cache
def get_data():
 key = 'hot-course'
 result = cache.get(key)
 if result:
 return result
 # 比较耗时的数据获取
 result = Course.objects.filter().order_by('-fav_num')[:10]
 cache.set(key, result, 600) # 保存至缓存
 return result

这样一般就能解决数据来源耗时问题,一般用了这个方式就不会再用模板碎片缓存了,不然内存中就有两个缓存了,一个是原始数据,另一个是渲染成 html 代码的结果。有点多余,内存宝贵应该用于刀刃上,而且两个缓存的方式极不优雅。

使用这种底层 api 后,还是需要把数据传递到视图层,如果是公共部分的如轮播部分的视图,是会被其他模板 include 的,那就需要其他视图函数也都获取一次数据,再传递到模板层。重复的代码会很多。

有没有一种好的办法解决这种情况呢?

优雅的改进碎片缓存

改进的碎片缓存需要能按需获取,最好不需要视图层的参与。这个要求可以通过标签来实现,我们来自己实现一下这个缓存标签,在此之前呢,需要做个通用的缓存工具,能够传入数据获取的函数来做回调,这部分其实和 Django 的 django.templatetags.CacheNode 类基本一样。我这边就写与其不一样的地方:

class UserCacheNode(Node):
 """
 优雅的自定义模板碎片缓存
 """
 def __init__(self, nodelist, expire_time_var, fragment_name, vary_on, cache_name, fun=None):
 # ...
 self.fun = fun # 用于数据获取的回调函数

 def render(self, context:dict):
 # ...
 if value is None:
  if self.fun: # 实行回调
  context.update(self.fun(*vary_on))
  value = self.nodelist.render(context)
  fragment_cache.set(cache_key, value, expire_time) # 保存至缓存
 return value

然后是制作自定义标签:

def get_hot_course():
 # 做会调用,函数返回字典
 print("call hot course")
 hot_courses = Course.objects.filter().order_by('stu_nums')[:5]
 return locals()

@register.tag('hot_course_cache') # 自定义的标签名称
def hot_course_cache(parser, token):
 nodelist = parser.parse(('endcache',))
 parser.delete_first_token()
 tokens = token.split_contents()
 cache_name = None

 return UserCacheNode(
 nodelist, parser.compile_filter(tokens[1]),
 tokens[2], # fragment_name can't be a variable.
 [parser.compile_filter(t) for t in tokens[3:]],
 cache_name,
 fun=get_hot_course, # 回调函数
 )

然后在模板中就可以这么使用:

{% load course_tag %}
{% hot_course_cache 500 hot_courses %}
 ...hot_courses...
{% endcache %}

通过用自定义标签的方式,就无需视图层的参与了,缓存标签的使用方式也和体系中的 cache 相似,由于是自定义的标签,一些 IDE 会有一些警告,比如我的开发环境:

如何优雅地改进Django中的模板碎片缓存详解

运行上是没问题的,IDE 可能对这类自定义标签的支持度不是很好吧。

参考

Django's cache framework

Custom template tags and filters

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python获取DLL和EXE文件版本号的方法
Mar 10 Python
python、java等哪一门编程语言适合人工智能?
Nov 13 Python
对numpy中轴与维度的理解
Apr 18 Python
python 实现登录网页的操作方法
May 11 Python
解决pycharm回车之后不能换行或不能缩进的问题
Jan 16 Python
PyQt5基本控件使用之消息弹出、用户输入、文件对话框的使用方法
Aug 06 Python
Python在OpenCV里实现极坐标变换功能
Sep 02 Python
Python 实现自动导入缺失的库
Oct 29 Python
python调用函数、类和文件操作简单实例总结
Nov 29 Python
Python requests设置代理的方法步骤
Feb 23 Python
PyCharm配置KBEngine快速处理代码提示冲突、配置命令问题
Apr 03 Python
python文本处理的方案(结巴分词并去除符号)
May 26 Python
Django框架多表查询实例分析
Jul 04 #Python
python 借助numpy保存数据为csv格式的实现方法
Jul 04 #Python
Python将一个CSV文件里的数据追加到另一个CSV文件的方法
Jul 04 #Python
python中csv文件的若干读写方法小结
Jul 04 #Python
Python画柱状统计图操作示例【基于matplotlib库】
Jul 04 #Python
pandas将numpy数组写入到csv的实例
Jul 04 #Python
Python实现的简单排列组合算法示例
Jul 04 #Python
You might like
PHP处理Oracle的CLOB实例
2014/11/03 PHP
php实现按天数、星期、月份查询的搜索框
2016/05/02 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
2019/03/12 PHP
JQuery实现的在新窗口打开链接的方法小结
2010/04/22 Javascript
NodeJS与Mysql的交互示例代码
2013/08/18 NodeJs
JavaScript中setInterval的用法总结
2013/11/20 Javascript
给事件响应函数传参数的四种方式小结
2013/12/05 Javascript
JavaScript实现LI列表数据绑定的方法
2015/08/04 Javascript
jQuery隐藏和显示效果实现
2016/04/06 Javascript
js简单判断flash是否加载完成的方法
2016/06/21 Javascript
Highcharts入门之基本属性
2016/08/02 Javascript
js简单获取表单中单选按钮值的方法
2016/08/23 Javascript
jQuery除指定区域外点击任何地方隐藏DIV功能
2017/11/13 jQuery
基于vue 动态菜单 刷新空白问题的解决
2020/08/06 Javascript
[56:56]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
python利用beautifulSoup实现爬虫
2014/09/29 Python
Python实现提取谷歌音乐搜索结果的方法
2015/07/10 Python
在Django的通用视图中处理Context的方法
2015/07/21 Python
python制作爬虫并将抓取结果保存到excel中
2016/04/06 Python
pytorch索引查找 index_select的例子
2019/08/18 Python
python 求定积分和不定积分示例
2019/11/20 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
2020/05/11 Python
python开发入门——列表生成式
2020/09/03 Python
python中round函数保留两位小数的方法
2020/12/04 Python
html5+css3进度条倒计时动画特效代码【推荐】
2016/03/08 HTML / CSS
国际化的太阳镜及太阳镜配件零售商:Sunglass Hut
2016/07/26 全球购物
LN-CC中国:高端男装和女装的奢侈时尚目的地
2019/09/14 全球购物
服装机修工岗位职责
2013/12/26 职场文书
安全生产宣传标语
2014/06/06 职场文书
纪律教育月活动总结
2014/08/26 职场文书
学生会个人总结范文
2015/02/15 职场文书
房地产销售助理岗位职责
2015/04/14 职场文书
2016年第32个教师节致辞
2015/11/26 职场文书
Mysql 如何批量插入数据
2021/04/06 MySQL
python 经纬度求两点距离、三点面积操作
2021/06/03 Python
Java GUI编程菜单组件实例详解
2022/04/07 Java/Android