2014-01-22 34 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.