Django通过信号使模板缓存无效

时间:2016-03-14 15:04:31

标签: python django templates caching invalidation

在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 %}

此块缓存视频页面上的评论。

开启信号(添加新评论时发生)我正在尝试使缓存失效:

@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)) - 始终返回None(缓存失效失败,因为检索到的key没有任何缓存),但我确信缓存效果很好并且{{1}是平等的。

我对tmpl_key === cache_key做错了吗?

2 个答案:

答案 0 :(得分:1)

我在代码中看不到任何错误,但您可以改进和简化它。 首先int minusQ = Integer.parseInt(new productQuantity.getBalance()) - Integer.parseInt(quant.getText()); 具有完全针对动态参数的make_template_fragment_key参数,因此您不必手动创建缓存键。

所以你会在模板中得到这样的东西:

vary_on

...并在python中:

{% cache 86400 cm video_content_type.id video.id %}
    {% include 'comments/index.html' with obj=video %}
{% endcache %}

唯一的变化是您需要另外将视频content_type id传递给您的模板(或至少对其进行硬编码),因为使用content_type名称不是一个好主意。

PS。也!我现在无法检查它,但我不确定使用像你这样的数学表达式是合法的,所以我用简单的秒数替换它。

答案 1 :(得分:1)

无法设置"复合缓存键"作为连接字符串。 Django模板引擎将时间段后面的下一个符号视为"缓存键"字符串。

在我的问题中,它是符号" *":

{% 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 %}

然后通过传递vary_on

中的make_template_fragment_key参数列表来使缓存无效
@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])