2014-01-22 32 views
15

我试图做cache_page与基于类的视图(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工作?我一直在挖掘到这了一段时间...

好像以前的解决方案不会再工作下去

+0

文档如果不追加你的urls.py我们将无法帮助...... – petkostas

回答

38

按照caching docs文档,来缓存CBV正确的方法是

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

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

+6

这感觉不对隐藏在缓存'urls.py',但是。 –

+0

@J.C.Leitão在这个答案中,我正在显示在URL中缓存CBV的正确方法,因为[链接的答案](http:// stackoverflow。com/questions/7841772/django-url-caching-failing-for-class-based-views)在当时已经过时了。如果你不想,你不必在urls.py中进行缓存。如果您愿意,您可以重写视图的'dispatch'方法(您可能会发现['method_decorator']](https://docs.djangoproject.com/en/1.8/topics/class-based-views/intro/#decorating有用的)。 – Alasdair

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) 
9

另一个很好的例子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" 
+0

太棒了!感觉好多了,把url包装在一个函数中 – Brobin

2

我创造了这个小混入发生器在views文件中执行缓存,而不是在URL conf中:

def CachedView(cache_time=60 * 60): 
    """ 
    Mixing generator for caching class-based views. 

    Example usage: 

    class MyView(CachedView(60), TemplateView): 
     .... 

    :param cache_time: time to cache the page, in seconds 
    :return: a mixin for caching a view for a particular number of seconds 
    """ 
    class CacheMixin(object): 
     @classmethod 
     def as_view(cls, **initkwargs): 
      return cache_page(cache_time)(
       super(CacheMixin, cls).as_view(**initkwargs) 
      ) 
    return CacheMixin 
1

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

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

你可以简单的装饰类本身,而不是覆盖的调度方法,或者使用一个混合的。

例如

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上decorating a method within a class based view.