クラスベースのビュー(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を機能させる他の方法はありますか?私はしばらくこれを掘り下げてきました...
以前のソリューションはもう機能しないようです
caching docs によると、URLにCBVをキャッシュする正しい方法は次のとおりです。
from Django.views.decorators.cache import cache_page
url(r'^my_url/?$', cache_page(60*60)(MyView.as_view())),
リンクした回答が古くなっていることに注意してください。デコレータの古い使用方法は削除されました( changeset )。
さらに別の良い例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"
ディスパッチメソッドをオーバーライドしたり、ミックスインを使用したりする代わりに、クラス自体を単純に装飾できます。
例えば
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のドキュメント クラスベースのビュー内のメソッドの装飾
クラスデコレータとして追加することも、リストを使用して複数を追加することもできます。
@method_decorator([vary_on_cookie, cache_page(900)], name='dispatch')
class SomeClass(View):
...
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
さらに別の答えとして、これが最も簡単で、テンプレートビューに固有であることがわかりました。
class CachedTemplateView(TemplateView):
@classonlymethod
def as_view(cls, **initkwargs): #@NoSelf
return cache_page(15 * 60)(super(CachedTemplateView, cls).as_view(**initkwargs))
クラスベースのビューに適したキャッシュソリューションが見つからず、独自に作成しました: 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)
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)