web-dev-qa-db-ja.com

クラスベースのビューを持つcache_page

クラスベースのビュー(TemplateView)でcache_pageを実行しようとしていますが、実行できません。私はここの指示に従いました:

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]

つまり、複数の引数を許可しません。 cache_pageを機能させる他の方法はありますか?私はしばらくこれを掘り下げてきました...

以前のソリューションはもう機能しないようです

28
KVISH

caching docs によると、URLにCBVをキャッシュする正しい方法は次のとおりです。

from Django.views.decorators.cache import cache_page

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

リンクした回答が古くなっていることに注意してください。デコレータの古い使用方法は削除されました( changeset )。

49
Alasdair

さらに別の良い例CacheMixin 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"
18
madjardi

ディスパッチメソッドをオーバーライドしたり、ミックスインを使用したりする代わりに、クラス自体を単純に装飾できます。

例えば

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のドキュメント クラスベースのビュー内のメソッドの装飾

9
Dayson

クラスデコレータとして追加することも、リストを使用して複数を追加することもできます。

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

URL confではなくviewsファイルでキャッシュを行うために、この小さなミックスインジェネレーターを作成しました。

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
3

さらに別の答えとして、これが最も簡単で、テンプレートビューに固有であることがわかりました。

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

クラスベースのビューに適したキャッシュソリューションが見つからず、独自に作成しました: 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)
2

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)
0
Phil Gyford