猿问

Django 1.11:为经过身份验证的用户禁用缓存

我们有一个用 python 2.7 和 django 1.11 编写的遗留应用程序(没有要迁移的资源)。它还用于grappelli授权。我们尝试Edit为一些页面添加链接(每个页面显示一个Round对象的详细信息),这些页面应该只对有权编辑回合的授权用户可见(APPNAME | round | Can change round在grappelli网络界面中)。在模板中,权限检查如下:


{% if perms.round.can_change_round %}

    &emsp;<a href="{{link_to_change_round}}" class="stuff-only-link">{% trans 'Edit' %}</a>

{% endif %}

当以下事件在很短的时间间隔内发生时,就会出现问题:

  1. 有权编辑回合的用户访问页面 - 并看到链接Edit

  2. 无权编辑回合的用户(例如匿名用户)访问同一页面 - 并且还看到了链接!

相关设置 ( settings.py) 是:

CACHES = {

    'default': {

    #   'BACKEND': 'django.core.cache.backends.dummy.DummyCache',

        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',

    }

}


SOLO_CACHE = 'default'

SOLO_CACHE_TIMEOUT = 5*60

当我将缓存更改为 时dummy,问题就消失了。因此,完全禁用授权用户的缓存似乎是一个显而易见的解决方案。更准确地说:


a) 如果用户是匿名的(大多数真实站点用户)——请求的页面可以写入缓存,也可以从缓存中读取;


b) 如果一个用户被授权(大约 5-7 个用户)——请求的页面不能写入缓存也不能从缓存中读取。


我如何实现这一目标?


MM们
浏览 113回答 2
2回答

慕妹3146593

您可以对模板的缓存部分进行分段,并从与用户相关的缓存部分中省略,或者根据记录的片段变量状态缓存它们

临摹微笑

经过一个小时的谷歌搜索后,找到并调整了答案。代码是:编辑:最初,缓存是基于功能的。因此,“/rounds/1”给出了与“/rounds/2”相同的(缓存的)值。我们将完整的 URL 添加到缓存键来解决这个问题。# -*- encoding: utf-8 -*-'''Python >= 2.4Django >= 1.0Author: eu@rafaelsdm.com'''# https://djangosnippets.org/snippets/2524/# https://stackoverflow.com/questions/20146741/django-per-user-view-caching# https://stackoverflow.com/questions/62913281/django-1-11-disable-cache-for-authentificated-usersfrom django.core.cache import cachedef cache_per_user(ttl=None, prefix=None):&nbsp; &nbsp; '''Decorador que faz cache da view pra cada usuario&nbsp; &nbsp; * ttl - Tempo de vida do cache, não enviar esse parametro significa que o&nbsp; &nbsp; &nbsp; cache vai durar até que o servidor reinicie ou decida remove-lo&nbsp;&nbsp; &nbsp; * prefix - Prefixo a ser usado para armazenar o response no cache. Caso nao&nbsp; &nbsp; &nbsp; seja informado sera usado 'view_cache_'+function.__name__&nbsp; &nbsp; * cache_post - Informa se eh pra fazer cache de requisicoes POST&nbsp; &nbsp; * O cache para usuarios anonimos é compartilhado com todos&nbsp; &nbsp; * A chave do cache será uma das possiveis opcoes:&nbsp; &nbsp; &nbsp; &nbsp; '%s_%s'%(prefix, user.id)&nbsp; &nbsp; &nbsp; &nbsp; '%s_anonymous'%(prefix)&nbsp; &nbsp; &nbsp; &nbsp; 'view_cache_%s_%s'%(function.__name__, user.id)&nbsp; &nbsp; &nbsp; &nbsp; 'view_cache_%s_anonymous'%(function.__name__)&nbsp; &nbsp; '''&nbsp; &nbsp; def decorator(function):&nbsp; &nbsp; &nbsp; &nbsp; def apply_cache(request, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # No caching for authorized users:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # they have to see the results of their edits immideately!&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; can_cache = request.user.is_anonymous() and request.method == 'GET'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Gera a chave do cache&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if prefix:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CACHE_KEY = '%s_%s'%(prefix, 'anonymous')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CACHE_KEY = 'view_cache_%s_%s_%s'%(function.__name__, request.get_full_path(), 'anonymous')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if can_cache:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response = cache.get(CACHE_KEY, None)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response = None&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not response:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print 'Not in cache: %s'%(CACHE_KEY)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response = function(request, *args, **kwargs)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if can_cache:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cache.set(CACHE_KEY, response, ttl)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return response&nbsp; &nbsp; &nbsp; &nbsp; return apply_cache&nbsp; &nbsp; return decorator然后在views.py:from cache_per_user import cache_per_user as cache_page#...##@cache_page(cache_duration)def round_detail(request, pk):
随时随地看视频慕课网APP

相关分类

Python
我要回答