Django開発者であれば、django.core.cache(サーバーサイドキャッシュ)には馴染みがあるでしょう。しかし、DjangoはHTTPキャッシュを効果的に制御できる、もう一つの強力なツールセットであるdjango.utils.cacheを提供しています。このモジュールは、サーバーの負荷を軽減し、ユーザーエクスペリエンスを向上させるために不可欠なHTTPヘッダーの管理に重点を置いています。

このポストでは、django.utils.cacheの主な機能と使い方を見ていきましょう。


django.core.cachedjango.utils.cacheの違い



最初に明確にしておくべきポイントです。

  • django.core.cache(サーバーサイドキャッシュ):

    • データベースのクエリ結果、複雑な演算結果、テンプレートの一部などをサーバーメモリ(RAM)、Redis、Memcachedなどに保存します。
    • 目的: サーバー内部の演算負荷を軽減し、応答生成速度を向上させます。
  • django.utils.cache(HTTPキャッシュ / クライアントサイドキャッシュ):

    • Cache-ControlVaryETagLast-ModifiedといったHTTP応答ヘッダーを設定します。
    • 目的: ブラウザやプロキシサーバーが応答をキャッシュするよう指示し、同じリクエストが発生した際にはサーバーに再リクエストせずにキャッシュされた応答を使用するようにします。

簡単に言えば、core.cacheデータをキャッシュし、utils.cacheHTTP応答をキャッシュする方法を制御します。


主なデコレーターと機能

django.utils.cacheモジュールは主にビュー(View)に適用するデコレーター形式で使用されます。

1. @cache_control

最も基本的でありながら強力なデコレーターです。Cache-Control HTTPヘッダーを詳細に制御することができます。

  • max_age: キャッシュが有効な時間(秒単位)。ブラウザはこの時間の間、キャッシュされたバージョンを使用します。
  • public=True: 応答が公開(public)キャッシュ(例: CDN、プロキシ)に保存される可能性があることを意味します。
  • private=True: 応答がユーザーブラウザなどの非公開(private)キャッシュにのみ保存されるべきことを意味します。(一般的にmax_ageとともに使用)
  • no_cache: キャッシュを使用する前に常にサーバーで有効性を検証させます。
  • no_store: 応答を絶対にキャッシュしないようにします。

例:

# views.py
from django.utils.cache import cache_control

# このビューの応答を1時間(3600秒)ブラウザキャッシュに保存
@cache_control(max_age=3600)
def my_public_view(request):
    # ...
    return response

# このビューは敏感なユーザー情報があるため、非公開キャッシュ(ブラウザ)にのみ30分間保存
@cache_control(private=True, max_age=1800)
def user_profile_view(request):
    # ...
    return response

2. @never_cache

名前の通り、このビューの応答を絶対にキャッシュしないように設定します。

Cache-Control: max-age=0, no-cache, no-store, must-revalidateヘッダーを追加し、ブラウザが応答をキャッシュしないように強く指示します。

例: (主に決済ページ、重要なフォーム提出ページなどに使用)

# views.py
from django.utils.cache import never_cache

@never_cache
def sensitive_form_view(request):
    # ...
    return response

Varyヘッダーを設定するために使用されます。Varyヘッダーは、キャッシュされた応答がどの条件に基づいて異なるかを伝える重要な役割を担います。

例えば、@vary_on_headers('User-Agent')を使用すると、モバイルとデスクトップのUser-Agentに応じて異なるHTMLを提供する際、キャッシュがこの二つを区別して保存するようになります。

@vary_on_cookieはクッキーの値に基づいてビューの内容が異なる時に使用されます。(例: セッションクッキーによりログイン/ログアウト状態が変わる場合)

例:

# views.py
from django.views.decorators.vary import vary_on_headers, vary_on_cookie

# User-Agent(モバイル/デスクトップ)とAccept-Language(言語設定)により
# キャッシュを別々に保存
@vary_on_headers('User-Agent', 'Accept-Language')
def content_view(request):
    # ...
    return response

# クッキー(セッション)により内容が異なるビュー
@vary_on_cookie
def user_specific_view(request):
    # ...
    return response

まとめ



django.utils.cacheはDjangoがHTTP標準を良く遵守し、クライアント側キャッシングを精密に扱えるよう支援する重要なモジュールです。

適切なCache-ControlVaryヘッダーの設定は、サーバーのトラフィックを劇的に減少させ、ユーザーがより速いロード速度を体験できる鍵となる戦略です。特に静的コンテンツや滅多に変更されないリストページにこのモジュールのデコレーターを活用すれば、大きなパフォーマンス向上が期待できます。