【Django(知識編)】HTML テンプレートの仕組み、読み込む順番を検証・実験してみた

reading html structureDjango

(最終更新月: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後に下記を追加した状態です

  1. INSTALLED_APPに「myfirstapp」というapp
  2. TEMPLATESのDIRSに「BASE_DIR / “templates”」

全体のフォルダ構成

templatesフォルダを2箇所に作成済

  1. srcフォルダ直下(src/templates)
  2. 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が読まれてしまっていたからなのではとこれを実験してみてわかりました!

ただ、実践ではほとんどのケースでは役に立たないような気もしてます 笑

とはいってもやっぱり「どうなってるの?」と思ったことがわかるって、楽しい!と改めて感じました

少しでもそんな思いが共有できてれば嬉しいです!

最後までご覧いただきありがとうございました!!!

タイトルとURLをコピーしました