Django で PC とモバイルで切り替わるキャッシュページデコレータを実装する方法

 同一URLでPCとモバイルでキャッシュページを切り替えるには、Varyヘッダを利用する方法などが考えられますが、
ここでは django-bpmobile を組み込んでいる場合に利用できる agent 判定を組み込んだ @cache_page デコレータの例を示す。
(agentの判定方法次第でキャリアごとにキャッシュすることも可能です。)

# -*- coding: utf-8 -*-
try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps  # Python 2.4 fallback.
 
from django.utils.decorators import available_attrs
from django.views.decorators.cache import cache_page
 
def cache_page_with_bpmobile(cache_timeout, nonmobile_key_prefix, mobile_key_prefix):
    """PCとモバイルに分けてキャッシュを保持するキャッシュページデコレータです。"""
    def __cache_page_with_bpmobile(view_func):
        # 引数 view_func をラップする関数を定義
        @wraps(view_func, assigned=available_attrs(view_func))
        def _cache_page_with_bpmobile(request, *view_args, **view_kwargs):
            # モバイル以外の場合
            if request.agent.is_nonmobile():
                # モバイル以外のキープリフィックスを設定
                cache_key_prefix = nonmobile_key_prefix
            # モバイルの場合
            else:
                # モバイルのキープリフィックスを設定
                cache_key_prefix = mobile_key_prefix
            # キープリフィックスを指定してcache_pageに処理を委託
            return cache_page(view_func, cache_timeout, key_prefix=cache_key_prefix)(request, *view_args, **view_kwargs)
        return _cache_page_with_bpmobile
    return __cache_page_with_bpmobile

 @cache_page_with_bpmobile デコレータは以下ように利用する。

views.py

@cache_page_with_bpmobile(cache_timeout=60*60, nonmobile_key_prefix='pc_cache', mobile_key_prefix='mobile_cache')
def top_page():
    ...