我正在开发一个 Django 1.4 项目并使用每个站点缓存编写一个简单的应用程序,如下所述:
https://docs.djangoproject.com/en/dev/topics/cache/#the-per-site-cache
我已经正确设置了本地 Memcached 服务器并确认页面正在被缓存。
然后我设置 CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True 因为我不想为经过身份验证的用户缓存页面。
我正在使用一个简单的视图进行测试,该视图返回一个带有 render_to_response 和 RequestContext 的模板,以便能够从模板访问用户信息,并且到目前为止缓存工作良好,这意味着它只为匿名用户缓存页面。
这是我的问题。我使用不访问用户信息的不同模板创建了另一个视图,并注意到即使用户已通过身份验证,该页面也正在被缓存。在测试了很多东西之后,我发现如果模板没有从用户上下文变量中打印一些东西,那么经过身份验证的用户会获得一个缓存页面。测试非常简单:在模板上打印用户,页面不会为经过身份验证的用户缓存,删除模板上的用户,在经过身份验证时刷新页面并检查 HTTP 标头,你会注意到你得到了一个缓存页面。您应该清除更改之间的缓存以更清楚地查看问题。
我进行了更多测试,发现我可以摆脱模板中的用户并在视图上打印 request.user(打印到开发服务器控制台),并且还解决了向经过身份验证的页面显示缓存页面的问题用户,但这是一个丑陋的黑客。
这里报告了一个类似的问题,但从未得到答案:
https://groups.google.com/d/topic/django-users/FyWmz9csy5g/discussion
我可能可以编写一个条件装饰器来检查是否 user.is_authenticated() 并基于此使用 @never_cache 在我的视图中,但这似乎违背了使用每个站点缓存的目的,不是吗?
"""
A decorator to bypass per-site cache if the user is authenticated. Based on django.views.decorators.cache.never_cache.
See: http://stackoverflow.com/questions/12060036/why-django-1-4-per-site-cache-does-not-work-correctly-with-cache-middleware-anon
"""
from django.utils.decorators import available_attrs
from django.utils.cache import add_never_cache_headers
from functools import wraps
def conditional_cache(view_func):
"""
Checks the user and if it's authenticated pass it through never_cache.
This version uses functools.wraps for the wrapper function.
"""
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view_func(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
if request.user.is_authenticated():
add_never_cache_headers(response)
return response
return _wrapped_view_func
任何避免需要额外装饰器的建议将不胜感激。
谢谢!