问题
在 Django 中,如何创建仅对经过身份验证的用户可见的页面的单个缓存版本(所有用户都相同)?
设置
我希望缓存的页面仅对经过身份验证的用户可用(他们@login_required
在视图上使用)。这些页面对于所有经过身份验证的用户都是相同的(例如,无需vary_on_headers
基于唯一用户进行设置)。
但是,我不希望未经身份验证的用户可以看到这些缓存页面。
到目前为止我尝试过的
- 页面级缓存(显示用于登录用户到未登录用户的页面)
- 考虑使用
vary_on_headers
,但我不需要为每个用户单独缓存页面 - 我检查了模板片段缓存,但除非我感到困惑,否则这不能满足我的需求
- 大量搜索(似乎每个人都想做相反的事情)
谢谢!
示例视图
@login_required
@cache_page(60 * 60)
def index(request):
'''Display the home page'''
return render(request, 'index.html')
settings.py(相关部分)
# Add the below for memcache
MIDDLEWARE_CLASSES += (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
# Enable memcache
# https://devcenter.heroku.com/articles/memcache#using_memcache_from_python
CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache'
}
}
解决方案
根据@Tisho 的回答,我解决了这个问题
decorators.py
在我的应用程序中创建文件- 将以下代码添加到它
- 将函数导入到
views.py
- 将其作为装饰器应用于我只想为登录用户缓存的视图
装饰器.py
from functools import wraps
from django.views.decorators.cache import cache_page
from django.utils.decorators import available_attrs
def cache_on_auth(timeout):
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
if request.user.is_authenticated():
return cache_page(timeout)(view_func)(request, *args, **kwargs)
else:
return view_func(request, *args, **kwargs)
return _wrapped_view
return decorator
对于已登录的用户,它将为未登录的用户缓存页面(或为他们提供缓存的页面),它只会为他们提供常规视图,该视图被装饰@login_required
并要求他们登录。