Django缓存仅限经过身份验证的用户 [英] Django Caching for Authenticated Users Only
问题描述
设置
我希望缓存的页面仅适用于已通过身份验证的用户(他们使用 @login_required
在视图上)。这些页面对于所有经过验证的用户都是相同的(例如,不需要根据唯一用户来设置 vary_on_headers
)。
但是,我不希望这些缓存页面对未经过身份验证的用户可见。
到目前为止我尝试过的内容
- 页面级高速缓存(显示用于登录用户的页面以供未登录的用户使用)
- 使用
vary_on_headers
,但我不需要为每个用户单独缓存页面。 - 我检出了模板片段缓存,但除非我感到困惑,满足我的需求
- 实质搜索(似乎每个人都想做相反的事情)
示例视图
@login_required
@ (请求,'index.html')
settings.py(相关部分)
#为memcache添加以下内容
MIDDLEWARE_CLASSES + =(
' django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
#启用memcache
#https:// devcenter。 heroku.com/articles/memcache#using_memcache_from_python
CACHES = {
'default':{
'BACKEND':'django_pylibmc.memcached.PyLibMCCache'
}
}
解决方案
根据@Tisho的回答,我解决了这个问题。
- 创建一个
装饰器。
- 将以下代码添加到它
- 在
中导入函数>
- 将它作为装饰器应用于我只想为登录用户缓存的视图
decorators.py
from functools im端口从django.views.decorators.cache导入缓存
从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):$ b $如果request.user.is_authenticated ):
return cache_page(timeout)(view_func)(request,* args,** kwargs)
else:
返回view_func(request,* args,** kwargs)
返回_wrapped_view
返回装饰器
对于登录用户,它会缓存页面他们是缓存的页面),它只会给它们定期的视图,该视图用 @login_required
装饰,并且需要它们登录。
默认 cache_page
装饰器接受一个变量c alled key_prefix
。但是,它只能作为字符串参数传递。所以你可以编写你自己的装饰器,它会根据 is_authenticated
值动态修改 prefix_key
。以下是一个例子:
from django.views.decorators.cache import cache_page
def cache_on_auth(超时):
def decorator(view_func):
@wraps(view_func,assigned = available_attrs(view_func))
def _wrapped_view(request,* args,** kwargs):
返回cache_page(timeout,key_prefix =_ auth_%s_%request.user.is_authenticated())(view_func)(request,* args,** kwargs)
return _wrapped_view
返回装饰器
然后在视图中使用它:
@cache_on_auth(60 * 60)
def myview(请求)
<然后,生成的cache_key将如下所示:
缓存键:
views.decorators.cache.cache_page。 _auth_False_.GET.123456.123456
如果用户已通过身份验证,并且
缓存键:
views.decorators.cache.cache_page._auth_True_.GET.789012.78 9012
如果用户未通过验证。
Question
In Django, how can create a single cached version of a page (same for all users) that's only visible to authenticated users?
Setup
The pages I wish to cache are only available to authenticated users (they use @login_required
on the view). These pages are the same for all authenticated users (e.g. no need to setup vary_on_headers
based on unique users).
However, I don't want these cached pages to be visible to non-authenticated users.
What I've tried so far
- Page level cache (shows pages intended for logged in users to non-logged in users)
- Looked into using
vary_on_headers
, but I don't need individually cached pages for each user - I checked out template fragment caching, but unless I'm confused, this won't meet my needs
- Substantial searching (seems that everyone wants to do the reverse)
Thanks!
Example View
@login_required
@cache_page(60 * 60)
def index(request):
'''Display the home page'''
return render(request, 'index.html')
settings.py (relevant portion)
# 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'
}
}
Solution
Based on the answer by @Tisho I solved this problem by
- Creating a
decorators.py
file in my app - Adding the below code to it
- Importing the function in
views.py
- Applying it as a decorator to the views I wanted to cache for logged in users only
decorators.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
For logged in users, it would cache the page (or serve them the cached page) for non-logged in users, it would just give them the regular view, which was decorated with @login_required
and would require them to login.
The default cache_page
decorator accepts a variable called key_prefix
. However, it can be passed as a string parameter only. So you can write your own decorator, that will dynamically modify this prefix_key
based on the is_authenticated
value. Here is an example:
from django.views.decorators.cache import cache_page
def cache_on_auth(timeout):
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
return cache_page(timeout, key_prefix="_auth_%s_" % request.user.is_authenticated())(view_func)(request, *args, **kwargs)
return _wrapped_view
return decorator
and then use it on the view:
@cache_on_auth(60*60)
def myview(request)
Then, the generated cache_key will look like:
cache key:
views.decorators.cache.cache_page._auth_False_.GET.123456.123456
if the user is authenticated, and
cache key:
views.decorators.cache.cache_page._auth_True_.GET.789012.789012
if the user is not authenticated.
这篇关于Django缓存仅限经过身份验证的用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!