Django缓存仅限经过身份验证的用户 [英] Django Caching for Authenticated Users Only

查看:320
本文介绍了Django缓存仅限经过身份验证的用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django中,如何创建一个页面的单个缓存版本(对所有用户来说都是相同的),这些版本仅对经过验证的用户可见?

b

设置



我希望缓存的页面仅适用于已通过身份验证的用户(他们使用 @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的回答,我解决了这个问题。


  1. 创建一个装饰器。

  2. 将以下代码添加到它

  3. 中导入函数>

  4. 将它作为装饰器应用于我只想为登录用户缓存的视图



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

  1. Creating a decorators.py file in my app
  2. Adding the below code to it
  3. Importing the function in views.py
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆