Djangoアプリ全体で使う変数をコンテキストプロセッサで提供
組み込み Template とかをみてると {{ MEDIA }} とかが出てきますが、これを自前で作る方法。同じアプリを複数サイトで立ち上げる必要が出てきて、区別の為、アプリごとにユニークな名前を表示したい。ただ、それだけの用途に使いました。
(Django 1.7 の admin のように基底クラスの中で変数を定義して継承、もしくはCookieに値をセット、なども気づいたのですが、今回は修正が少なくて済む context processor を用意する方法を選択)
環境:
Template と Context
Template 上で扱いたいオブジェクトや値は、Viewからcontextに入れて渡すというのが通常の流れ。
view.py
class IndexView(TemplateView): template_name = 'index.html' ... context['application_name'] = 'HogeHoge'
app/templates/index.html
<h1>{{ application_name }}</h1>
しかし、全Viewに対してアプリ名を渡すとなると、各Viewのcontextにアプリ名を渡していく修正が発生するので手間がかかる。
Context Processor で Context に値を追加
そこで、新しく必要な値を渡す コンテキスト プロセッサを作り、context を生成する度に、特定の変数を渡せるようにします( {{ MEDIA }} のような)。
今回は、アプリ名を渡したいだけなので、settings.py に新しい変数を定義して、それを参照するという事をやります(settings.py中の変数名は、大文字を使おうという記述があったと思うので、それにならって記載)。
app/settings.py :
from django.conf import global_settings TEMPLATE_CONTEXT_PROCESSORS = \ global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( 'app.context_processors.app_name', ) APP_NAME = 'My App'
Django1.6 の場合 : TEMPLATE_CONTEXT_PROCESSORS は、デフォルト値も記載がなかったので、グローバルで定義されている値に追加してます。リスト形式なのでカンマを忘れずに。
app/context_processors.py
from django.conf import settings def media(request): return {'APP_NAME': settings.APP_NAME}
上記の設定が終われば、Viewで処理しているテンプレートで次の記述を行うことで、変数を参照できるようになります。View毎にcontextに変数を渡す必要はありません。
app/templates/index.html
<h1>{{ APP_NAME }}</h1>
感想
context processor という名前から、仰々しく思ってしまったのですが、手を入れてしまえば簡単。内部まで、動作がはっきり見えるのは、オープンソースの気持ちいいところだなぁと感じました。
この解法がベストか?という点は、持ちネタが少ないため分からないというのが正直な所です。(ASPでいうところの、アプリケーション変数みたいな起動中に自由に参照できる変数みたいな、ライトなイメージの機能はあったりしないのでしょうかね?F/W違うので、無茶とは思いつつも)
# もっと良い方法があれば、教えてください〜
参考サイト
- Djangoのテンプレートでsettings.pyのMEDIA_URLを参照 - DaemonFreaks Blog
- MEIDA_URL の参照を用意する手順。2007年ということで、Django 1.0ぐらいの時代?コードは、ほぼこちらを参照させていただきました!
- 【Django1.4】テンプレート内でviews.pyから渡さなくてもrequest変数を使えるようにする - ぐぐったら出てきた。
- request変数を、よく参照する場合の手法