概要
HTMLや埋め込まれたデータを含むテンプレートを使ったアプリケーションの基本。流れは以下の通り。
- テンプレートを表示させるアプリケーションの作成と登録
- テンプレートを保存するディレクトリーとテンプレートファイルの作成
- テンプレートを呼び出すビュー関数の作成
- ルーティング設定
ここでは以下のことを整理している。
- テンプレートの配置場所
- テンプレートの参照方法
- テンプレート言語(DTL)の概要
関連記事
プロジェクトの準備
プロジェクトディレクトリーをtemplatebasics
とし、settings.py
などを含むサブディレクトリーをconfig
とする。
|
$ mkdir templatebasics && cd templatebasics $ django-admin startproject config . |
初期設定とサーバー起動で動作確認しておく。
アプリケーションの作成・登録
テンプレートを表示させるアプリケーションtemplatedemo
を作成する。
|
$ python3 manage.py startapp templatedemo |
そしてアプリケーションをsettings.py
のINSTALLED_APPS
に追加登録する。
|
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'templatedemo', ] |
テンプレート配置
初期設定
テンプレートの配置場所はsettings.py
のTEMPLATES
で設定する。
|
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] |
DIRS
は任意の場所・ディレクトリー名のパスを設定する。またAPP_DIR
をTrue
に設定すると、各アプリケーションディレクトリー下のtemplates
ディレクトリーが探索される。
複数のテンプレートディレクトリーは一括して同列に扱われ、各ディレクトリーのサブディレクトリーも再帰的に探索される。
デフォルトの設定では、各アプリケーションディレクトリー下のtemplates
ディレクトリーのみが対象となっている。
配置場所
ここでは、以下の場所にテンプレートディレクトリーを置いて設定していく。
- 2か所にテンプレートディレクトリーを配置し、いずれのファイル名とも
index.html
としている
- プロジェクト直下のディレクトリー名は任意だが、簡明のため
templates
とする
- 2つのテンプレートディレクトリーは併せて参照されるので、アプリケーション下の方は区別のためにサブディレクトリーを設けている
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
templatebasics/ ├── config │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── templatedemo │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── [templates] <- APP_DIRS=Trueで探索される │ │ └── [templatedemo] │ │ └── [index.html] │ ├── tests.py │ └── views.py └── [templates] <- DIRSで設定:名前は任意 └── [index.html] |
アプリケーション下
テンプレートディレクトリー作成
作成したアプリケーションディレクトリーtemplatedemo
の下にtemplates
ディレクトリーを作成し、その下に更にサブディレクトリーtemplatedemo
を作成する。
テンプレートファイル作成
作成したサブディレクトリー下にindex.html
ファイルを作成して以下を記述。
|
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>アプリケーション下</title> </head> <body> <h1>アプリケーション下</h1> </body> </html> |
プロジェクト直下
settings.py編集
TEMPLATES
のDIRS
にプロジェクト直下のtemplates
ディレクトリーを探索するよう追加。
|
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['templates'], 'APP_DIRS': True, ........ }, ] |
os.path
を使う方法もありその場合はimport os
が必要になるが、上記の記述でも同じ効果。
テンプレートディレクトリー作成
プロジェクトディレクトリー直下にtemplates
ディレクトリーを作成する。サブディレクトリーは作成しない。
テンプレートファイル作成
作成したtemplates
ディレクトリー下にindex.html
ファイルを作成して以下を記述。
|
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>プロジェクト直下</title> </head> <body> <h1>プロジェクト直下</h1> </body> </html> |
view関数の作成とルーティング
view関数の作成
アプリケーションディレクトリーtemplatedemo
のviews.py
を編集して、view関数を定義する。
view関数でレンダリングするテンプレートを指定するため、プロジェクト直下とアプリケーションディレクトリー下2か所のテンプレートに対応する関数を記述している。要点は以下のとおり。
def 関数名(request):
で定義
- テンプレートを呼ぶ戻り値は
render
関数
- 第1引数は受け取ったrequest
- 第2引数はテンプレートファイルのパス
- テンプレートファイルのパスについて
TEMPLATES
で設定したすべてのテンプレートディレクトリー下が一括して扱われる
- テンプレートディレクトリー以下の相対パスとする
|
rom django.shortcuts import render def index_project(request): return render(request, 'index.html') def index_application(request): return render(request, 'templatedemo/index.html') |
複数テンプレートディレクトリーが一括して扱われ、テンプレートの指定がテンプレートディレクトリーからの相対パスとなるため、サブディレクトリーを設定した意義が確認できる。
view関数のルーティング登録
これらのview関数をURLから呼び出すためurls.py
に記述を追加する。
|
from django.contrib import admin from django.urls import path from templatedemo import template_application, template_project urlpatterns = [ path('admin/', admin.site.urls), path('application', template_application) path('project', template_project) ] |
確認
ここで開発用Webサーバーを起動して、ブラウザーで以下の入力に対応したページが表示されるのが確認できる。
localhost:8000/project
localhost:8000/application
DTL~テンプレート言語
概要
テンプレートにはHTMLのほかに、view関数から受け取った変数を埋め込んだり、繰り返しや条件分岐による出力の変更といった制御をさせることができる。そのための言語をDTL (Django Template Language)と言う。
{{ 変数 }}
:変数の内容を展開してHTMLに埋め込む
{% 文 %}
:for
~endfor
によるループやif
~elif
~endif
による条件分岐で出力を制御する
変数の展開
たとえばtemplatedemo
アプリケーションのviews.py
で、index_application
関数を以下のように変更する。
|
def index_application(request): text = 'アプリケーション下' return render(request, 'templatedemo/index.html', {'title': text}) |
ここでは、変数text
を定義して、これを'text'
をキーとする辞書の値としてrender
関数の第3引数に渡している。
次に、templatedemo
アプリケーション下のindex.html
テンプレートを以下のように変更する。
|
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>{{ title }}</title> </head> <body> <h1>{{ title }}</h1> </body> </html> |
表示結果は、ブラウザーの上部またはタブと見出しに同じ「アプリケーション下」が表示される。
このように、ビュー側で処理した結果を変数としてテンプレートに渡し、HTMLとして表示させることができる。
制御構造
先のindex_application
関数を以下のように変更する。
|
def index_application(request): context = { 'title': '浦島太郎', 'scenes': ['亀を助ける', '玉手箱をもらう', '竜宮城に行く', '浜へ帰る', '玉手箱を開けて年寄りになる'], } return render(request, 'templatedemo/index.html', context) |
ここでは第3引数をcontext
とし、この変数に2つの要素を持つ辞書を入れている。1つ目の要素はタイトル、2つ目の要素は物語のシーンを収めた配列としている。
これを受け取るindex.html
を以下のように変更する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>{{ title }}</title> </head> <body> <h1>{{ title }}</h1> <p>物語のシーン</p> <ol> {% for scene in scenes %} <li>{{ scene }}</li> {% endfor %} </ol> </body> </html> |
scenes
で渡された配列の要素を、DTLのfor
~endfor
でループしながら取り出し、li
要素として並べている。この結果、出力されたHTMLでは5つのシーンがリストとして表示される。
同じテンプレートを使って、タイトルとシーンを桃太郎やかぐや姫などと変化させることができる。