J'essaie de faire cache_page avec des vues basées sur la classe (TemplateView) et je ne suis pas en mesure de le faire. J'ai suivi les instructions ici:
Django - Echec de la mise en cache des URL pour les vues basées sur des classes
ainsi qu'ici:
https://github.com/msgre/hazard/blob/master/hazard/urls.py
Mais je reçois cette erreur:
cache_page has a single mandatory positional argument: timeout
J'ai lu le code pour cache_page et il a ceci:
if len(args) != 1 or callable(args[0]):
raise TypeError("cache_page has a single mandatory positional argument: timeout")
cache_timeout = args[0]
ce qui signifie qu'il ne permettra pas plus d'un argument. Existe-t-il un autre moyen de faire fonctionner cache_page? J'ai creusé dans cela pendant un certain temps ...
Il semble que les solutions précédentes ne fonctionneront plus
Selon le cache des documents docs, la méthode correcte pour mettre en cache un CBV est
url(r'^my_url/?$', cache_page(60*60)(MyView.as_view())),
Notez que la réponse que vous avez liée est obsolète. L'ancienne façon d'utiliser le décorateur a été supprimée ( changeset ).
encore un autre bon exemple CacheMixin de 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)
cas d'utilisation:
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"
Vous pouvez simplement décorer la classe elle-même au lieu de remplacer la méthode de répartition ou d'utiliser un mixin.
Par exemple
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 sur décorer une méthode dans une vue basée sur les classes.
Vous pouvez l'ajouter en tant que décorateur de classe et même en ajouter plusieurs à l'aide d'une liste:
@method_decorator([vary_on_cookie, cache_page(900)], name='dispatch')
class SomeClass(View):
...
J'ai créé ce petit générateur de mixin pour faire la mise en cache dans le fichier views
, au lieu de dans l'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
Encore une autre réponse, nous avons trouvé que ceci était plus simple et spécifique aux vues modèles.
class CachedTemplateView(TemplateView):
@classonlymethod
def as_view(cls, **initkwargs): #@NoSelf
return cache_page(15 * 60)(super(CachedTemplateView, cls).as_view(**initkwargs))
Je n'ai pas trouvé de solution de cache efficace pour les vues basées sur les classes et j'ai créé le mien: https://Gist.github.com/svetlyak40wt/1112126018
C'est un mix pour une classe. Ajoutez-le avant la classe de base principale et implémentez la méthode get_cache_params comme ceci:
def get_cache_params(self, *args, **kwargs):
return ('some-prefix-{username}'.format(
username=self.request.user.username),
3600)
Voici ma variante du CachedView()
mixin. Je ne souhaite pas mettre la vue en cache si l'utilisateur est authentifié, car son affichage des pages lui sera propre (par exemple, son nom d'utilisateur, son lien de déconnexion, etc.).
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)