Django每用户视图缓存

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_pagevary_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.

  • 虽然它回答了这个问题,这是值得大家注意的是它不一样,如果你想实现供客人使用的专用缓存,工作,因为每一个客户都有不同的会话cookie(在大多数安装). (4认同)

Ron*_*Ron 5

我找到了解决方案!

\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\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我刚刚对此进行了测试,可以确认它适用于 Django 1.6.8。 (3认同)

小智 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)