Ron*_*Ron 6 python django caching django-views
我需要一个每用户缓存.遗憾的是,常规视图缓存不支持基于用户的缓存.
我尝试了这样的模板片段缓存:
{% load cache %}
{% cache 500 "mythingy" request.user %}
... HTML stuff ...
{% endcache %}
Run Code Online (Sandbox Code Playgroud)
但是地狱很慢.
有没有人知道更快的方式来实现我的需求?
谢谢!
ife*_*aju 19
从django> = 1.7开始,在视图中使用cache_page和vary_on_cookie修饰符应解决此问题.
这样的事情.
from django.views.decorators.vary import vary_on_cookie
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
@vary_on_cookie
def view_to_cache(request):
...
Run Code Online (Sandbox Code Playgroud)
注意装饰器的顺序,vary_on_cookie应该在它到达之前进行处理cache_page.
我找到了解决方案!
\n\n这是这个葡萄牙语代码片段,它的作用就像一个魅力!
\n\n好处是我不需要摆弄我的模板代码,而是可以使用干净的装饰器!
\n\n代码包含在下面
\n\n# -*- encoding: utf-8 -*-\n\'\'\'\nPython >= 2.4\nDjango >= 1.0\n\nAuthor: eu@rafaelsdm.com\n\'\'\'\nfrom django.core.cache import cache\n\ndef cache_per_user(ttl=None, prefix=None, cache_post=False):\n \'\'\'Decorador que faz cache da view pra cada usuario\n * ttl - Tempo de vida do cache, n\xc3\xa3o enviar esse parametro significa que o\n cache vai durar at\xc3\xa9 que o servidor reinicie ou decida remove-lo \n * prefix - Prefixo a ser usado para armazenar o response no cache. Caso nao\n seja informado sera usado \'view_cache_\'+function.__name__\n * cache_post - Informa se eh pra fazer cache de requisicoes POST\n * O cache para usuarios anonimos \xc3\xa9 compartilhado com todos\n * A chave do cache ser\xc3\xa1 uma das possiveis opcoes:\n \'%s_%s\'%(prefix, user.id)\n \'%s_anonymous\'%(prefix)\n \'view_cache_%s_%s\'%(function.__name__, user.id)\n \'view_cache_%s_anonymous\'%(function.__name__)\n \'\'\'\n def decorator(function):\n def apply_cache(request, *args, **kwargs):\n # Gera a parte do usuario que ficara na chave do cache\n if request.user.is_anonymous():\n user = \'anonymous\'\n else:\n user = request.user.id\n\n # Gera a chave do cache\n if prefix:\n CACHE_KEY = \'%s_%s\'%(prefix, user)\n else:\n CACHE_KEY = \'view_cache_%s_%s\'%(function.__name__, user) \n\n # Verifica se pode fazer o cache do request\n if not cache_post and request.method == \'POST\':\n can_cache = False\n else:\n can_cache = True\n\n if can_cache:\n response = cache.get(CACHE_KEY, None)\n else:\n response = None\n\n if not response:\n response = function(request, *args, **kwargs)\n if can_cache:\n cache.set(CACHE_KEY, response, ttl)\n return response\n return apply_cache\n return decorator\nRun Code Online (Sandbox Code Playgroud)\n
小智 5
对于使用 django Rest 框架以及其他框架的人:
def cache_per_user(timeout):
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
user_id = 'not_auth'
if request.user.is_authenticated:
user_id = request.user.id
return cache_page(timeout, key_prefix="_user_{}_".format(user_id))(view_func)(request, *args, **kwargs)
return _wrapped_view
return decorator
Run Code Online (Sandbox Code Playgroud)
用法:
@method_decorator(cache_per_user(3600))
Run Code Online (Sandbox Code Playgroud)