Django 通过信号使模板缓存无效
Django invalidate template cache by signal
在 Django 模板中,我有复合缓存键变量:
{% with video.id|to_str as video_id %}
{% with 'cm'|add:"video"|add:video_id as tmpl_key %}
{% cache 3600 * 24 tmpl_key %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
{% endwith %}
{% endwith %}
此块缓存视频页面上的评论。
On signal(在添加新评论时发生)我正在尝试像这样使缓存无效:
@receiver(comment_was_posted)
def comment_was_posted_handler(sender, **kwargs):
comment = kwargs['comment']
cache_key = "cm" + str(comment.content_type) + str(comment.object_pk)
key = make_template_fragment_key(cache_key)
print(cache.get(key))
cache.delete(key)
print(cache.get(key))
- 始终 returns None
(缓存失效失败,因为检索到的 key
没有任何缓存),但我确定缓存有效well 和 tmpl_key === cache_key
相等。
我是不是在 make_template_fragment_key
上做错了什么?
我在你的代码中看不到任何错误,但你可以改进和简化它。
首先,make_template_fragment_key
有 vary_on
参数完全用于动态参数,因此您不必手动创建缓存键。
所以你会在你的模板中得到这样的东西:
{% cache 86400 cm video_content_type.id video.id %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
... 在 python 中:
@receiver(comment_was_posted)
def comment_was_posted_handler(sender, **kwargs):
comment = kwargs['comment']
key = make_template_fragment_key('cm', vary_on=(comment.content_type.id, comment.object_pk))
cache.delete(key)
唯一的变化是您需要另外将视频 content_type id 传递给您的模板(或至少对其进行硬编码),因为使用 content_type 名称不是一个好主意。
PS。还!我现在无法检查,但我不确定像你那样使用数学表达式是否合法,所以我用简单的秒数替换了它。
无法将 "compound cache key" 设置为串联字符串。 Django 模板引擎将时间部分后的下一个符号视为 "cache key" 字符串。
在我的问题中是符号“*”:
{% cache 3600 * 24 tmpl_key %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
因此,django 将 '*' 视为缓存键,将 '24'、'tmpl_key' 视为 vary_on 参数。
正确代码:
您需要像这样传递缓存参数:
{% cache 3600 video_comments video.id %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
然后通过在 make_template_fragment_key
中传递 vary_on
参数列表使缓存无效
@receiver(comment_was_posted)
def comment_was_posted_handler(sender, **kwargs):
comment = kwargs['comment']
if str(comment.content_type) == "video":
key = make_template_fragment_key('video_comments', [comment.object_pk])
在 Django 模板中,我有复合缓存键变量:
{% with video.id|to_str as video_id %}
{% with 'cm'|add:"video"|add:video_id as tmpl_key %}
{% cache 3600 * 24 tmpl_key %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
{% endwith %}
{% endwith %}
此块缓存视频页面上的评论。
On signal(在添加新评论时发生)我正在尝试像这样使缓存无效:
@receiver(comment_was_posted)
def comment_was_posted_handler(sender, **kwargs):
comment = kwargs['comment']
cache_key = "cm" + str(comment.content_type) + str(comment.object_pk)
key = make_template_fragment_key(cache_key)
print(cache.get(key))
cache.delete(key)
print(cache.get(key))
- 始终 returns None
(缓存失效失败,因为检索到的 key
没有任何缓存),但我确定缓存有效well 和 tmpl_key === cache_key
相等。
我是不是在 make_template_fragment_key
上做错了什么?
我在你的代码中看不到任何错误,但你可以改进和简化它。
首先,make_template_fragment_key
有 vary_on
参数完全用于动态参数,因此您不必手动创建缓存键。
所以你会在你的模板中得到这样的东西:
{% cache 86400 cm video_content_type.id video.id %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
... 在 python 中:
@receiver(comment_was_posted)
def comment_was_posted_handler(sender, **kwargs):
comment = kwargs['comment']
key = make_template_fragment_key('cm', vary_on=(comment.content_type.id, comment.object_pk))
cache.delete(key)
唯一的变化是您需要另外将视频 content_type id 传递给您的模板(或至少对其进行硬编码),因为使用 content_type 名称不是一个好主意。
PS。还!我现在无法检查,但我不确定像你那样使用数学表达式是否合法,所以我用简单的秒数替换了它。
无法将 "compound cache key" 设置为串联字符串。 Django 模板引擎将时间部分后的下一个符号视为 "cache key" 字符串。
在我的问题中是符号“*”:
{% cache 3600 * 24 tmpl_key %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
因此,django 将 '*' 视为缓存键,将 '24'、'tmpl_key' 视为 vary_on 参数。
正确代码:
您需要像这样传递缓存参数:
{% cache 3600 video_comments video.id %}
{% include 'comments/index.html' with obj=video %}
{% endcache %}
然后通过在 make_template_fragment_key
vary_on
参数列表使缓存无效
@receiver(comment_was_posted)
def comment_was_posted_handler(sender, **kwargs):
comment = kwargs['comment']
if str(comment.content_type) == "video":
key = make_template_fragment_key('video_comments', [comment.object_pk])