2014-01-22 5 views
15

Ich versuche, cache_page mit klassenbasierten Ansichten (TemplateView) zu tun, und ich kann nicht. Ich folgte Anweisungen hier:cache_page mit klassenbasierten Ansichten

Django--URL Caching Failing for Class Based Views

sowie hier:

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

Aber ich bekomme diese Fehlermeldung:

cache_page has a single mandatory positional argument: timeout 

ich den Code für cache_page gelesen und es hat die folgenden:

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

was bedeutet, dass es nicht mehr als 1 Argument erlaubt. Gibt es einen anderen Weg, um cache_page zu arbeiten? Ich habe für einige Zeit in diese gegraben ...

Es scheint, wie die bisherigen Lösungen arbeiten gewohnt mehr

+0

Wenn Sie nicht Ihre urls.py anhängen wir helfen können, zu wont ... – petkostas

Antwort

38

Nach den caching docs docs, der richtige Weg, ein CBV zwischenzuspeichern ist

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

Beachten Sie, dass die Antwort, die Sie verknüpft haben, veraltet ist. Die alte Art der Verwendung des Dekorators wurde entfernt (changeset).

+6

Es fühlt sich nicht richtig versteckt das Caching in die 'urls.py', aber gut. –

+0

@ J.C.Leitão in dieser Antwort, ich zeigte die korrekte Möglichkeit, ein CBV in den URLs zwischenzuspeichern, weil die [verknüpfte Antwort] (http: // stackoverflow.com/questions/7841772/django-url-caching-failing-for-class-based-views war damals veraltet. Sie müssen das Caching in urls.py nicht durchführen, wenn Sie nicht möchten. Sie können die Methode 'dispatch' Ihrer Ansicht überschreiben, wenn Sie dies bevorzugen (Sie finden [' method_decorator'] (https://docs.djangoproject.com/en/1.8/topics/class-based-views/intro/#decorating) (die Klasse) nützlich). – Alasdair

2

habe ich nicht eine gute Cache-Lösung für die Klasse basierter Ansichten gefunden und meine eigenen erstellt: https://gist.github.com/svetlyak40wt/11126018

Es ist ein mixin für eine Klasse. Fügen Sie es vor der Hauptbasisklasse und implementieren Methode get_cache_params wie folgt aus:

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

noch ein weiteres gutes Beispiel 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) 

usecase:

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

Brilliant! Fühlt sich viel besser dabei an, die URL in einer Funktion zu verpacken – Brobin

2

ich dieses kleine mixin Generator erstellt das Zwischenspeichern in der Datei views statt in der 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

Noch eine andere Antwort, wir fanden dies am einfachsten und ist spezifisch für Vorlagenansichten.

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

Sie können einfach die Klasse schmücken sich stattdessen den Versandweg vorran oder eine mixin verwenden.

Zum Beispiel

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

Verwandte Themen