Django:テンプレートの配置と名前空間
Django では,各アプリケーションごとにテンプレートを置くためのディレクトリを作成する(ここで言うアプリケーションとは「python manage.py startapp [app-name]
で作られるパッケージ(ディレクトリ)」のこと).そのディレクトリ構造が少し複雑なのでその仕組みを覚書として残しておく.
以下,参考にした公式チュートリアルのページ.
Django のテンプレートを置くためのディレクトリ構造について
今,下記のようなディレクトリ構造の Django プロジェクトがあるとする.デフォルトで作られるプロジェクトに,polls
という一つのアプリケーションが追加された状態である.
. ├── config │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── polls # 追加されたアプリケーション ├── __init__.py ├── admin.py ├── apps.py ├── migrations ├── models.py ├── tests.py ├── urls.py └── views.py
Django では,アプリケーションpolls
にテンプレートを追加する際には,ディレクトリ polls
下に templates
というテンプレート用のディレクトリを作ってテンプレートを置くと Django 側で上手く読み込んでくれる.実際には,config/settings.py
の INSTALLED_APPS
に追加されたアプリケーションの templates
サブディレクトリを検索してテンプレートを読み込んでくれる.
しかし,一つ注意点がある.例えば,index.html
というテンプレートを polls
アプリケーションに追加する際には,polls/templates/index.html
ではなく,polls/templates/polls/index.html
というディレクトリ構造でテンプレートを置く必要がある.
- ダメ:
polls/templates/index.html
- OK:
polls/templates/polls/index.html
これは以下のような理由による.
Template namespacing
Now we might be able to get away with putting our templates directly in polls/templates (rather than creating another polls subdirectory), but it would actually be a bad idea. Django will choose the first template it finds whose name matches, and if you had a template with the same name in a different application, Django would be unable to distinguish between them. We need to be able to point Django at the right one, and the easiest way to ensure this is by namespacing them. That is, by putting those templates inside another directory named for the application itself.
はじめての Django アプリ作成、その 3 | Django ドキュメント | Django より引用
解釈すると,
- Django は最初に名前が一致したテンプレートを選択する.
- 異なるアプリケーションの
templates
ディレクトリに同じ名前のテンプレートがある場合,それらを区別できない(例えば,index.html
は被りやすい). - Django に正しいテンプレートを認識させる簡単な方法の一つは,名前空間を与えることである.
要するに,区別できないなら名前空間与えてそれで Django 側に判断してもらえばええやんという話.polls
にテンプレートディレクトリを追加した後のディレクトリは以下のようになる.
. ├── config │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── polls # 追加されたアプリケーション ├── __init__.py ├── admin.py ├── apps.py ├── migrations ├── models.py ├── templates # templates サブディレクトリ │ └── polls │ └── index.html ├── tests.py ├── urls.py └── views.py
これで Python の View からテンプレートにアクセスするときは polls/index.html
という名前でアクセスできるようになった.