context_processors とは、
「テンプレートに共通で使いたい変数を自動的に渡す仕組み」 のことです。
Djangoはテンプレートを描画する際、RequestContext という仕組みで変数を管理しています。
このとき、context_processors に登録された関数が自動的に呼び出され、それぞれの関数が返す辞書がテンプレート変数に追加されます。
つまり、一度設定してしまえば、どのテンプレートでも {{ 変数名 }} で使えるようになります。
更新日:
投稿日:
Djangoで開発していると、どのページでも共通して使いたい情報があります。
たとえば「デフォルト画像のURL」や「サイトタイトル」「現在のURL」などです。
これらを各ページのviewで一つ一つ変数を設定してテンプレートに渡すのは面倒です。
私のアプリ(KakuhanApp)でも、OGP用の画像をどのページでも指定できるようにしたかったので、
<meta property="og:image" content="{{ default_thumbnail_url }}"> のように書くだけで自動的に値が入る仕組みを作りました(OGP用の画像は絶対パスでないと表示されないため、{% static 'images/thumbnail.png' %}では✖)。
そのときに活用したのが 「context_processors」 です。
この記事では、context_processors とは何なのか、どうやって使うのかを紹介していきます。
context_processors とは、
「テンプレートに共通で使いたい変数を自動的に渡す仕組み」 のことです。
Djangoはテンプレートを描画する際、RequestContext という仕組みで変数を管理しています。
このとき、context_processors に登録された関数が自動的に呼び出され、それぞれの関数が返す辞書がテンプレート変数に追加されます。
つまり、一度設定してしまえば、どのテンプレートでも {{ 変数名 }} で使えるようになります。
複数のページで共通して使いたい変数を自動的に渡したいとき に便利です。
context_processorsを使えば「共通で渡したい変数」を一か所にまとめて、Djangoが自動的に全テンプレートに渡してくれるようになります。
イメージとしては、
「アプリ全体でいつでも呼び出せる共通の変数を登録しておく場所」
という感じです。
私の場合、OGP画像の <meta> タグに使うURLを複数ページで統一したかったので、{{ default_thumbnail_url }} という変数をどのテンプレートでも使えるようにしました。
例として「全てのテンプレートに共通の画像URLの絶対パスを渡す」仕組みを実装します。
まず、設定フォルダに context_processors.py を作成します。
私の場合、共通機能をまとめる core フォルダがあるのでそちらに context_processors.py を作成しました。
core/ ├─ __init__.py ├─ context_processors.py └─ …
そして core/context_processors.py に以下を記述します。
from django.templatetags.static import static
def default_thumbnail(request):
""" すべてのテンプレートに '画像の絶対パス' を渡す """
url_thumb = request.build_absolute_uri(static("images/default_thumbnail.png"))
return { "default_thumbnail_url": url_thumb,}
次に、設定ファイルのTEMPLATESのcontext_processorsに登録します。
TEMPLATES =
[
{ ...
"OPTIONS": {
"context_processors": [
...
"core.context_processors.default_thumbnail", # これを追加 設定フォルダにcontext_processorsをおいた場合は"設定フォルダ名.context_processors.default_thumbnail"
], }, }, ]
これで準備完了です。
すべてのテンプレートで以下のように書くだけでcontext_processorで設定した画像URLの絶対パス利用できます。
{{ default_thumbnail_url }}
context_processors を使うと、「複数のテンプレートで共通の変数を使いたい」という要望を
とてもシンプルに実現できます。
いちいち各viewからテンプレートに変数を渡さなくて済むのでとても楽です。
渡したい共通変数の追加や修正もcontext_processorsを書き換えればよいだけなので拡張性や保守性も上がります。