Djangoのdjango.template.loaders.app_directories.load_template_sourceの挙動はおかしい
Djangoプロジェクト内で、アプリケーションのプロトタイプver.2を作成中に気がついた。タイトル通り、Djangoのdjango.template.loaders.app_directories.load_template_sourceの挙動はおかしい。
例を挙げると、Djangoプロジェクト内で2つのアプリケーションapp1,app2を作って、それぞれのアプリケーション内にtemplatesディレクトリを作り、それぞれのアプリケーションで使うテンプレートファイルを保存したとする。
このように
+はディレクトリ、-はファイル + project + app1 + template - index.html + app2 + template - index.html
ここまで作業してsettings.pyにアプリケーションをインストールする。それぞれのアプリにurls.pyを記述しURLConfを脱カップリングして、開発用サーバを起動してアプリケーションのトップページを表示させようとすると、、、
ここで、テンプレートを使う側は、app1内のviews.pyでindex.htmlテンプレートを使うときはapp1/templates/index.htmlによって描画されて、app2のviews.pyでindex.htmlテンプレートを使うときはapp2/templates/index.htmlによって描画がなされると考えるはず。
実際は、settings.pyのINSTALLED_APPSに記述された順番でどちらか一方だけが描画に使われる。INSTALLED_APPSにapp1を先に記述した場合はapp1にアクセスした場合もapp2にアクセスした場合もapp1/templates/index.htmlがテンプレートに使われる。app2を先に記述した場合はapp1にアクセスしてもapp2にアクセスしてもapp2/templates/index.htmlがテンプレートに使われる。
Loader型
http://djangoproject.jp/doc/ja/1.0/ref/templates/api.html#loader
django.template.loaders.app_directories.load_template_source ファイルシステム上の Django アプリケーションからテンプレートをロードします。このローダは INSTALLED_APPS の各アプリケーションについて templates サブディレクトリを探します。ディレクトリが存在すれば、 Django はその中からテンプレートを探します。 これはすなわち、個々のアプリケーションにテンプレートを保存しておけるということです。このローダを使うと、 Django アプリケーションをデフォルトのテンプレート付きで配りやすくなります。 例えば、以下のように設定します: INSTALLED_APPS = ('myproject.polls', 'myproject.music') get_template('foo.html') は以下のディレクトリを順番に探します: * /path/to/myproject/polls/templates/foo.html * /path/to/myproject/music/templates/foo.html
ちょっと待った!それじゃ異なるアプリケーション間で同名のテンプレートが共有されてしまうじゃないか。
アプリケーション毎にtemplatesディレクトリを作ったのはテンプレートをアプリケーション間で独立させるためで、あるアプリケーションのテンプレートを他のアプリケーションのテンプレートディレクトリから持ってこられると困る。まるで変数のルックアップが内側のブロックから検索されるのではなくソースコードの1行目から検索されるような猛烈な違和感がある。
x = 10 def f(): x = 100 print x f() # => 100になってほしい!
django.template.loaders.app_directories.load_template_sourceに、アプリケーション直下のtemplatesディレクトリだけをサーチさせる方法が見つけられない。もしかしたらどこかに記述されているのに気がついていないだけかもしれないけれど。