我一直在我的django应用程序中实现缓存,并通过缓存API和模板片段缓存使用每个视图缓存。 在我的一些页面上,我使用自定义django模板标记,此标记由第三方开发人员提供,它在其模板标记中获取一些参数,然后向远程服务器发出请求,通过XML获取响应,以及然后在我的页面中呈现结果。 太棒了 - 我想我可以使用片段缓存轻松缓存它,所以我:
{% load cache %}
{% cache 500 request.user.username %}
{% load third party custom tags %}
{% expensive custom tag set that gets stuff from a third party server via xml %}
{{ some.stuff}}
{% endcache %}
麻烦无论我做什么,请求仍然被解雇到远程服务器,似乎Django不喜欢缓存这些自定义模板标签。我知道memcached工作得很好,对于其他视图和模板,一切正常。我在做一些与片段缓存不兼容的事情吗?有没有办法绕过它?
答案 0 :(得分:3)
如果您尝试缓存的模板片段无法被腌制,则memcached将无法存储它并将引发异常。从我可以收集的内容来看,渲染Django模板时生成的异常被抑制。由于您的自定义标记正在执行HTTP请求,因此可能以某种方式将套接字对象(无法进行pickle)存储到模板片段中。
如果是这种情况,我能想到的唯一方法就是修改自定义标签以摆脱任何剩余的套接字对象。
答案 1 :(得分:0)
您是否尝试过为缓存片段使用其他名称?使用request.user.username可能存在以下几个原因:
如果用户未登录, request.user.username可能为空, 导致非命名缓存 片段
如果用户已登录,则会执行此操作 调用第三方模板标记 每3个用户至少一次 mintues
也许值得尝试将缓存片段名称重命名为test:
{% cache 500 customxml %}
我还尝试在缓存标记之外加载第三方模板标记,如下所示:
{% load cache third_party_custom_tags %}
{% cache 500 request.user.username %}
{% expensive custom tag set that gets stuff from a third party server via xml %}
{{ some.stuff}}
{% endcache %}
我不确定缓存框架是否缓存模板标记的结果。如果这不起作用,我会看看模板标签在幕后做了什么,并使用Django的low-level cache重新实现模板标签。
答案 2 :(得分:0)
我认为问题是自定义标记,正如您所建议的那样。
我不同意request.user.username是一个问题,因为该主题的文档实际上以此为例,我在测试中使用了内部缓存(例如帖子数),以及它运作良好。
低级缓存可能很有用,但我会看看你的自定义标签,看看哪些不是缓存。如果没有代码,很难猜测,但我的猜测会像时间或其他变量一样被返回,因为它导致它强制更新(如果XML提取任何更改Django的数据可能会强制更新,具体取决于在其他设置上)。我在Django的缓存方面遇到了不同的结果,所以我会看一下你的XML feed,看它是否会导致任何停止缓存。
答案 3 :(得分:0)
我认为这与自定义标记无关。
我们最终重写了Django缓存标记,因为我们需要的控制比提供的控制更多。您可以自己复制一份,并将一些调试打印语句粘贴到其中。特别是,检查文件名(假设您正在缓存文件)并查看正在生成的内容。可能是它不应该改变(由于某种未知的原因),这意味着它总是需要重新渲染然后封闭的块。
查看django / templatetags / cache.py。它只有63行代码。