具有基于类的视图的cache_page

时间:2014-01-22 20:42:40

标签: django django-class-based-views

我正在尝试使用基于类的视图(TemplateView)执行cache_page,但我无法做到。我按照说明操作:

Django--URL Caching Failing for Class Based Views

以及这里:

https://github.com/msgre/hazard/blob/master/hazard/urls.py

但是我收到了这个错误:

cache_page has a single mandatory positional argument: timeout

我读了cache_page的代码,它有以下内容:

if len(args) != 1 or callable(args[0]):
    raise TypeError("cache_page has a single mandatory positional argument: timeout")
cache_timeout = args[0]

这意味着它不会允许超过1个参数。有没有其他方法让cache_page工作?我一直在挖这个......

以前的解决方案似乎不再适用

8 个答案:

答案 0 :(得分:46)

根据caching docs,在网址中缓存CBV的正确方法是:

from django.views.decorators.cache import cache_page

url(r'^my_url/?$', cache_page(60*60)(MyView.as_view())),

请注意,您链接的答案已过期。旧的使用装饰器的方法已被删除(changeset)。

答案 1 :(得分:17)

另一个很好的示例CacheMixin from cyberdelia github

class CacheMixin(object):
    cache_timeout = 60

    def get_cache_timeout(self):
        return self.cache_timeout

    def dispatch(self, *args, **kwargs):
        return cache_page(self.get_cache_timeout())(super(CacheMixin, self).dispatch)(*args, **kwargs)

用例:

from django.views.generic.detail import DetailView


class ArticleView(CacheMixin, DetailView):
    cache_timeout = 90
    template_name = "article_detail.html"
    queryset = Article.objects.articles()
    context_object_name = "article"

答案 2 :(得分:8)

您可以简单地装饰类本身,而不是覆盖调度方法或使用mixin。

例如

from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator

@method_decorator(cache_page(60 * 5), name='dispatch')
class ListView(ListView):
...

Django docs decorating a method within a class based view.

答案 3 :(得分:4)

您可以将其添加为类装饰器,甚至可以使用列表添加多个:

var x = func( /* whatever integer we like here */ )

答案 4 :(得分:3)

我创建了这个小的mixin生成器来在{ name: { type: String }, users: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}] } 文件中进行缓存,而不是在URL conf中进行缓存:

var userId = new mongoose.Schema.ObjectId('57d9503ef10d5ffc08d6b8cc');
events.find({members: { $elemMatch : { users: { $in: [userId]} } }})

答案 5 :(得分:2)

我没有为基于类的视图找到一个好的缓存解决方案并创建了我自己的:https://gist.github.com/svetlyak40wt/11126018

这是一堂课的混音。在主基类之前添加它并实现方法get_cache_params,如:

def get_cache_params(self, *args, **kwargs):
   return ('some-prefix-{username}'.format(
       username=self.request.user.username),
            3600)

答案 6 :(得分:2)

另一个答案是,我们发现这是最简单的,并且特定于模板视图。

class CachedTemplateView(TemplateView):
    @classonlymethod
    def as_view(cls, **initkwargs): #@NoSelf
        return cache_page(15 * 60)(super(CachedTemplateView, cls).as_view(**initkwargs))

答案 7 :(得分:0)

这是CachedView() mixin的变体 - 如果用户经过身份验证,我不想缓存视图,因为他们对页面的看法对他们来说是独一无二的(例如包括他们的用户名,注销链接等。)

class CacheMixin(object):
    """
    Add this mixin to a view to cache it.

    Disables caching for logged-in users.
    """
    cache_timeout = 60 * 5 # seconds

    def get_cache_timeout(self):
        return self.cache_timeout

    def dispatch(self, *args, **kwargs):
        if hasattr(self.request, 'user') and self.request.user.is_authenticated:
            # Logged-in, return the page without caching.
            return super().dispatch(*args, **kwargs)
        else:
            # Unauthenticated user; use caching.
            return cache_page(self.get_cache_timeout())(super().dispatch)(*args, **kwargs)