страница кэша с представлениями на основе классов

Я пытаюсь сделать cache_page с представлениями на основе классов (TemplateView), и я не могу. Я следовал инструкциям здесь:

Django--ошибка кэширования URL для представлений на основе классов

и здесь:

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 работать?? Я копался в этом некоторое время...

похоже, что предыдущие решения больше не будут работать

8 ответов


по словам кэширование документов docs, правильный способ кэширования CBV -

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

обратите внимание, что ответ, на который вы ссылаетесь, устарел. Старый способ использования декоратора был удален (изменений).


еще один хороший пример CacheMixin С GitHub профиль cyberdelia

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"

вы можете просто украсить сам класс вместо переопределения метода dispatch или использования mixin.

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 on украшения метод в классе с учетом.


Я создал этот маленький генератор mixin для кэширования в 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

Я не нашел хорошего решения для кэша для представлений на основе классов и создал свой собственный: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)

еще один ответ, мы нашли это самым простым и специфичным для представлений шаблонов.

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

вы можете добавить его в качестве декоратора класса и даже добавить несколько, используя список:

@method_decorator([vary_on_cookie, cache_page(900)], name='dispatch')
class SomeClass(View):
   ...

вот моя вариация CachedView() mixin-я не хочу кэшировать представление, если пользователь аутентифицирован, потому что их представление страниц будет уникальным для них (например, включите их имя пользователя, ссылку выхода и т. д.).

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)