Django コンテキストプロセッサでテンプレートコンテキストに共通の変数を埋め込む

Djangoの全てのhtmlテンプレートで共通の変数を埋め込む。

テンプレートコンテキスト(以下コンテキスト)に、変数名をキーとして、値を値として埋め込めばいい。 方法はとりあえず3通りある。

1つ1つのビューに書く

ビューが少なければあまり手間ではないが、変更するたびに全てを更新しないといけない。このことを考えるとまあ選択すべきではない方法になる。

クラスベースビューの基底クラスを作成し継承する

クラスベースビューで実装している場合に取れる方法。しかしこのためだけに基底クラスを追加するのも…。しかも、新たに規定クラスが必要になった時も少し手間が増える。といっても、継承元を少し付け替えるくらいだと思うが。

もしこの方法をとるなら、ベースクラスに共通のコンテキストの生成用メソッドを作成すればよいか。

しかし、次の方法が楽なので、この方法は取らない。

コンテキストプロセッサを使う

Djangoの素敵仕様であるcontext_processorを利用する方法。Djangoconfigにて指定する関数。コンテキストを生成するときに記載した順に呼び出されるもの。

指定する関数はdjango.http.HttpRequestインスタンスを引数にとり、コンテキストに追加する辞書を返すものにするのが仕様。

返した値がコンテキストに追加されるので、htmlテンプレートで使えるようになる。

することは、

  • コンテキストプロセッサ本体(関数)の用意する
  • Djangoのconfigファイルにて、コンテキストプロセッサ本体を使用するよう指定する
  • テンプレートを用意する

実装の例。まずは関数から:

# app/context_processors.py
from django.http import HttpRequest

def some_processor(request: HttpRequest):
    # 何かテンプレートコンテキストに追加するものを生成
    # dic = create_dict()
    # return dic
    return {
        'some_test_msg': '後から効いてくるスパイス'
    }

次に設定に記述。configファイルのTEMPLATESOPTIONScontext_processorsに1つ追加する:

# django config file
...

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # この4つはデフォルトであるはず
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # これ↓を追加
                'app.context_processors.some_processor',
            ],
        },
    },
]

この2つの追記だけで全てのビューのコンテキストに希望のものを埋め込むことができる。

上の例で埋め込んだ変数はテンプレートにて:

...
これは、<b>{{ some_test_msg }}</b>です。
...

のようにすることでhtmlに出力される。このテンプレートを他のテンプレートのベースとすることで有効活用できる。

よほどの事がなければコンテキストプロセッサでいい

実装漏れということもないし、Djangoの仕様に沿っていることもあって、コンテキストプロセッサを利用するのが最も簡単で安心な方法だろう。

もしかしたらデコレータも使えるかもしれないが、コンテキストプロセッサの方が簡単に扱えるだろう。

特定ビューの除外や特定ビューのみ受け付けるのも、request引数をチェックすれば簡単だ。

コンテキストプロセッサはテンプレートコンテキスト以外でも有効に使えるので、思いつけると賢い実装ができる。

以上です。


広告

https://amzn.to/3i01cQl
タイトルとURLをコピーしました