django - ventana - cache_page con vistas basadas en clase
vistas basadas en clases django (8)
Aquí está mi variante de la CachedView()
: no quiero CachedView()
en caché la vista si el usuario está autenticado, porque su vista de las páginas será única para ellos (por ejemplo, incluir su nombre de usuario, enlace de cierre de sesión, 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)
Estoy intentando hacer cache_page con vistas basadas en clase (TemplateView) y no puedo. Seguí las instrucciones aquí:
Django: error de almacenamiento en caché de URL para vistas basadas en clase
así como aquí:
https://github.com/msgre/hazard/blob/master/hazard/urls.py
Pero me sale este error:
cache_page has a single mandatory positional argument: timeout
Leí el código para cache_page y tiene lo siguiente:
if len(args) != 1 or callable(args[0]):
raise TypeError("cache_page has a single mandatory positional argument: timeout")
cache_timeout = args[0]
lo que significa que no permitirá más de 1 argumento. ¿Hay alguna otra manera de hacer que cache_page funcione? He estado investigando esto por algún tiempo ...
Parece que las soluciones anteriores ya no funcionan
Creé este pequeño generador de mezclas para hacer el almacenamiento en caché en el archivo de views
, en lugar de en la 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
De acuerdo con los documentos de la memoria caché , la forma correcta de almacenar un CBV es
url(r''^my_url/?$'', cache_page(60*60)(MyView.as_view())),
Tenga en cuenta que la respuesta a la que está vinculado no está actualizada. La antigua forma de usar el decorador ha sido eliminada ( changeset ).
No encontré una buena solución de caché para vistas basadas en clases y creé la mía: https://gist.github.com/svetlyak40wt/11126018
Es un mixin para una clase. Agréguelo antes de la clase base principal e implemente el método get_cache_params así:
def get_cache_params(self, *args, **kwargs):
return (''some-prefix-{username}''.format(
username=self.request.user.username),
3600)
Otra respuesta más, encontramos que esto es más simple y es específico de las vistas de plantilla.
class CachedTemplateView(TemplateView):
@classonlymethod
def as_view(cls, **initkwargs): #@NoSelf
return cache_page(15 * 60)(super(CachedTemplateView, cls).as_view(**initkwargs))
Puedes agregarlo como un decorador de clase e incluso agregar varios usando una lista:
@method_decorator([vary_on_cookie, cache_page(900)], name=''dispatch'')
class SomeClass(View):
...
Simplemente puede decorar la clase en sí, en lugar de anular el método de envío o usar un mixin.
Por ejemplo
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 en decorar un método dentro de una vista basada en clase.
otro buen ejemplo de 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)
caso de uso:
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"