Djangoのディレクトリ構成はLaravelやRailsといった類似ライブラリーとは大きく違った方針を取っています。
なぜ統一した「Template(Static)」ディレクトリを採用せずに「アプリケーションの要素か」を基準に区分しているか、それは各アプリケーションのViewの関心からディレクトリ構成を外すことができるからです。単一のコンポーネントの中にTemplateやStaticがあることによってプロジェクトディレクトリ/templates/
の配置に振り回されることがなく、固有の差し替えが必要な場合はプロジェクトディレクトリ/templates/
配下に差し替えたTemplateを配置することで差し替えをView等をいじることなく行うことが可能です。今回はDjangoにおけるディレクトリ構成の観点からTemplatesやStaticを扱う際にについて気を付けるべきところをまとめてみました。
Templates/Static共通して言えること
Templates/Static共通の特性として以下が挙げられます。
- settings.py内に必要な設定を書くことでファイル検索ロジックが変更可能
- 名前がかぶったとき最初に見つかったファイルを適用
ファイル検索ロジックを変更できる機能そして、最初のファイルを適用する特性から思わぬところから名前空間の衝突によるバグが発生することがあります。そのためなのか、Djangoのプラクティスには「プロジェクトディレクトリ/templates(static)/
にすべてのテンプレートを集約するのが良い。」という記述が時々みられます。確かに1回限りのWEBサイトを作る場合については、アプリケーションのモジュール化を行わないため、Templates/Staticの名前空間の問題を回避する一つの選択肢として検討してもいいかもしれません。しかしながら、WEBアプリを作成する際Templates・Static配下のディレクトリ構成がアプリケーションの関心に含まれてしまうことは、Viewの関心する範囲が大きくなってしまっている状態であることは留意し、アプリケーションのTemplateはできる限りアプリケーション内に閉じ込めましょう。
テンプレートエンジンの挙動についての仕様は「テンプレートエンジンのサポート」に詳しく記載されています。
公式ドキュメントにおけるTemplatesのディレクトリ構成についての言及
TemplatesはDjangoのdesign-philosophiesで9つも言及されてるほど重要度の高い機能です。
チュートリアルではチュートリアル3、チュートリアル7、reusable-appsの3回にわたってTemplatesについての言及が行われています。
チュートリアル3では何も設定を行っていないときアプリケーションのtemplates
配下を検索することとコラム「Template namespacing」内でアプリケーション同士でテンプレート名の衝突が起きたとき、Djangoは区別することができないためにアプリケーションにちなんだ名前空間を配置してほしいという記載があります。
Templatesの検索ロジック
チュートリアル3ではデフォルトの検索ロジックがアプリケーション配下のtemplates
ディレクトリからloader.get_template()関数として指定されたものを検索してきます。
例えば以下のようなディレクトリを仮定し、いずれかのアプリのviews.py内でloader.get_template('hoge.html')
が呼び出されたときを考えます。まず、app1,app2のtemplatesからhoge.htmlがあるかを検索します。app1のtemplatesにhoge.html
があるのでそれをtemplateとして解釈します。
このような挙動をするため名前の衝突というリスクと常に隣り合わせです。チュートリアル内コラム「Template namespacing」では、(ex:polls/templates/polls
)名前空間を作るようにというプラクティスが書かれています。
project/
app1/
templates/
hoge.html
app2/
templates/
huga.html
project/
settings.py
manage.py
再利用性のためのtemplateの配置
「特定のサイト固有の要素」と「再利用ができる要素」として明確に区別し、再利用できる要素についてはアプリケーションのテンプレートディレクトリに配置した方が良いとチュートリアル7内で記載されています。これはreusable-apps内でアプリケーションをプロジェクトに依存させるのではなく自己完結させるためにテンプレートディレクトリをこのような配置にした方が良いと記載されています。
テンプレートの継承もTemplate構成にはなくてはならない概念のため一読してみるとよいでしょう。
Staticについて
Staticはチュートリアル1ではチュートリアルにて作成したアプリケーション配下のStaticディレクトリ内に配置されています。Staticファイルに関する言及はチュートリアルでは少ないが、「How to manage static files (e.g. images, JavaScript, CSS)」、「How to deploy static files」ではStaticファイルの扱い方について詳しく言及されています。それらによると、StaticファイルはDjangoアプリケーションからではなくnginx等から直接配信することがパフォーマンスの観点から推奨されています。そのほかにStatic関係では注意しなければならないこととして以下が記載されています。
- Debugの値によって機能が変わる部分がある(runserver時に自動でstaticファイルを集める等)
- Templateと同様にstaticファイルは名前空間が分けられていないため、独自に名前空間のためのディレクトリを切る必要がある。
「The staticfiles app」というStaticファイルのための設定や補助コマンドについてまとめて書かれているページも一緒に見ることで特にデプロイプロセスを考える際の助けになるかと思います。
まとめ
再利用するコードはプロジェクトのルートディレクトリやプロジェクトの設定を置くディレクトリに入れるのではなくアプリケーションに入れ、アプリケーション固有の命名をつけることでライブラリ化のハードルをぐっと下げることになります。Djangoのベストプラクティスの記事はありますが「なぜこのプラクティスがDjangoのドキュメントと違うのか」という観点で改めて公式Documentを読んで実際のコードに落とし込むことでよりライブラリーをうまく使ったアプリケーションを作っていきましょう。