(最終更新月:2021年8月)
DjangoではHTMLファイルを
appフォルダ > templatesフォルダ > appフォルダ > HTMLファイル
というフォルダ構成で保存します
ただ、実際にviews.pyでテンプレートを読み込むときには、
templates_name = "appフォルダ/HTMLファイル"
とし、templatesフォルダなどは記載しません
これはどういった仕組みなのでしょうか?
当記事では、
Django テンプレートの仕組み、どのようにDjangoがHTMLファイルを取りに行っているか
を解説していきます
実際のところ、特に決まりを守っていれば仕組みを理解していなくてもアプリ開発には問題はありませんが、知っておくとエラーが出てしまった場合や、appが複雑になってきた場合に役に立ちます
ぜひここでDjangoにおけるテンプレートの仕組み、を理解しておきましょう!
【実験①】わざとエラーを起こしてみた
存在しないファイルをextendsしてみました
{% extends "base/base.html" %}
すると、「TemplateDoesNotExist」エラーが、
どうやら、上から順番に読んでいって見つからない場合にこのエラーがでるようですね!
※そもそもの設定やフォルダ構成などどうなってるかが気になるという方はこちらの章を先にご覧ください
【実験②】新しいappを追加してみた
新たなappを追加したときはどの時点で読み込むリストに組み込まれるのでしょうか
appの追加時点では?
新しいapp「templateTester」 を追加し、先程の画面へ
エラーの画面も特に変化無し
INSTALLED_APP変更・追記時点
settings.pyのINSTALLED_APPSに入れるも
特に変化無し
templatesフォルダ等作成後
app「templateTester」フォルダー内に、templatesフォルダ > templateTesterフォルダを作ると、
django.template.loaders.app_directories.Loader
: /home/xxxx/itc-django/src/templateTester/templates/base/base.html (Source does not exist)
がリストの末尾に追加されました!
templatesフォルダ等を作成すると自動的にDjangoはHTMLを探しに行ってくれるんですね!
【実験③】settings.py TEMPLATES-> DIRに違うフォルダ名も追加してみる
settings.pyのTEMPLATES DIRSはリストになっていることから複数指定にチャレンジ!
「build」というフォルダを追加してみました
'DIRS': [BASE_DIR / "templates", BASE_DIR / "build"],
すると先ほどのエラー画面では、
django.template.loaders.filesystem.Loader
: /home/xxxx/itc-blog/itc-django/src/build/base/base.html (Source does not exist)
2行目にbuildも追加されました!!
【補足】print()で見てみた
TEMPLATES内のDIR
settings.py内で、
print(TEMPLATES[0]["DIRS])
DIRSを見てみると、
[OUTPUT]
[ PosixPath('/home/xxxxxxx/itc-django/src/templates'), PosixPath('/home/xxxxxxx/itc-django/src/build') ]
PosixPathというメソッドが出てきましたね!
BASE_DIR / “templates”
ちなみに、ただ「BASE_DIR / “templates”」をprintすると
print(BASE_DIR / "templates")
[OUTPUT]
/home/xxxxxxx/itc-django/src/templates
TEMPLATES DIRS内では、PosixPathメソッドが出てきているのに対して、単に「BASE_DIR / “templates”」をprintするだけだと文字列が返るのみというのがわかりました
不思議な感じがするので、この辺りも簡単に調べましたがよくわかりませんでした
なぜPosixPathが出てくるのかわかりませんが、テンプレートを探す際には重要な役割を果たしているんだと思います
今回スタート時点の設定・フォルダ構成
今回のそもそもの設定はこんな感じでした!
settings.py
INSTALLED_APPS = [ ..., ..., 'myfirstapp', ] . . . TEMPLATES = [ { ..., 'DIRS': [BASE_DIR / "templates"], ...., ...., }, ]
startproject後に下記を追加した状態です
- INSTALLED_APPに「myfirstapp」というapp
- TEMPLATESのDIRSに「BASE_DIR / “templates”」
全体のフォルダ構成
templatesフォルダを2箇所に作成済
- srcフォルダ直下(src/templates)
- app「myfirstapp」フォルダ直下( src/myfirstapp/templates/myfirstapp/)
. ├── db.sqlite3 ├── main │ ├── init.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── myfirstapp │ ├── init.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── init.py │ ├── models.py │ ├── templates │ │ └── myfirstapp │ │ ├── context-view.html │ │ ├── second-view.html │ ├── tests.py │ ├── urls.py │ └── views.py └── templates ├── base.html
まとめ
settings.pyで「TEMPLATES」の設定をすると、
プロジェクト直下のtemplatesフォルダ→admin内のtemplatesフォルダ→auth内のtemplatesフォルダ、を経て各app直下のtemplatesフォルダが読まれるということがわかりました!
過去に、django-allauthのtemplatesを書き換えた際に反映されない!なんてことが起きたことがありました
これもapp直下のフォルダに入れていたため、先にadminが読まれてしまっていたからなのではとこれを実験してみてわかりました!
ただ、実践ではほとんどのケースでは役に立たないような気もしてます 笑
とはいってもやっぱり「どうなってるの?」と思ったことがわかるって、楽しい!と改めて感じました
少しでもそんな思いが共有できてれば嬉しいです!
最後までご覧いただきありがとうございました!!!