
【第6回】Djangoで日記アプリを作ろう ~Djangoテンプレート言語編~
2021.12.20
【第6回】Djangoで日記アプリを作ろう ~Djangoテンプレート言語編~
前回は、UpdateView と DeleteView を利用して、日記の編集画面と削除画面を作成しました。
今回は、Django テンプレート言語を利用して、画面の装飾を工夫してみましょう。
上記機能の作成を通して、以下の内容を新しく学んでいきます。
- Django テンプレート言語とは?
- テンプレートの継承
- widget を利用してフォームに class 属性を付与する方法
- django-widget-tweak の使い方
- django で bootstrap4 を利用する方法
それではまず、Django テンプレート言語について学んでいきましょう!
Djangoテンプレート言語とは
Django テンプレートとは、Django において HTML を生成するための仕組みです。
そして、Django テンプレート言語は、その HTML 生成を支援する言語です。
この言語を利用することで、テンプレートの中に動的なコンテンツを、簡単に埋め込むことができます。
実を言うと、この言語はこれまでの連載の中で、たくさん利用してます。
HTML に、フォームを作成するための、 {{ form }} という記述を行なっていました。
これがまさしく、テンプレート言語を用いた表現です。
今回は、まず Django テンプレート言語の基本概念である、「変数」と「タグ」を学びましょう。
また、テンプレートの継承という概念を利用して、以下の2つをあげる取り組みをしていきましょう。
- これまで作成したテンプレートの可読性
- 作成効率
変数
Django テンプレート言語では、 {{ }} という表現は、変数と呼ばれます。
主にビューで処理したデータを、テンプレート内部で利用するために使います。
これまで、CreateView や DetailView を用いて、日記の作成画面や詳細画面を作ってきました。
それらビューは、フォームや日記詳細データを、form や diary といった変数に与えます。
Django テンプレート言語では、それら変数を {{ }} という形で呼び出し、テンプレート内部で利用することができるわけです。
タグ
テンプレート言語では、もう一つ代表的な表現があります。
それがタグと呼ばれるもので、 {% %} というように表現されます。
主にタグは、Django テンプレートが用意する、組み込み機能を利用する場合に利用されます。
例えば、 {% now "Y年m月d日" %} というタグは、現在時刻を Y 年 m 月 d 日 形式で、HTML 上に表示します。
このような便利な組み込みタグがあるので、動的なコンテンツでも簡単なものであれば、ビューで実装する必要性はありません。
次の章では、「block タグ」と「extends タグ」を利用して、テンプレートの継承という操作を行なっていきましょう。
テンプレートの継承とは
テンプレートの継承とは、まず画面レイアウトの雛形となる「親テンプレート」を作り、その親テンプレートに各画面独自のコンテンツを加えてテンプレートを作成していくことです。
Web ページは、大きく分けると、以下の3つで構成されています。
- ヘッダー
- ボディ
- フッター
ヘッダーやフッターは、全てのページ共通といったこともよくありますね。
その場合は、まずページ共通の部分であるヘッダーとフッターを、親テンプレートで定義します。
そのテンプレートを継承する形で、他のテンプレートを作成していけば、同じ内容をコーディングする必要がありません。
また、ヘッダーやフッターの改修のとき、親テンプレートさえ変えてあげれば OK です。
これなら、改修コストも大きく削減できますね!
親テンプレートの作成
今回は、これまで作成してきたテンプレートから、共通の部分を抜き出した親テンプレートを作成してみます。
templates ディレクトリに、base.html という名前で、テンプレートを作成しましょう。
それに、以下のようなコードを記述して下さい。
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang="jp"> <head> <meta charset="UTF-8"> <title>MyDjangoApp</title> </head> <body> {% block content %} {% endblock %} </body> </html> |
日記投稿画面や日記の編集画面などで、共通の内容を抜き出してきました。
base.htmlのポイント
先ほどの html ファイルのポイントは、1つだけです。
<body>タグの中に記載された
1 2 | {% block content %} {% endblock %} |
の部分です。
base.html を継承したテンプレートでは、このブロックの部分にテンプレート独自の要素を追加することができます。
content という部分は、このブロックの名前です。
content という名前のブロックだけでなく、異なる名前の付いたブロックを作成することもできます。
既存テンプレートを継承した形に改修
index.html
では試しに、index.html を、親テンプレートを継承した形に改修してみましょう!
1 2 3 4 5 6 | {% extends 'base.html' %} {% block content %} <h1>Diary App by Django</h1> <h2><a href="{% url 'diary:diary_create' %}">日記の投稿</a></h2> <h2><a href="{% url 'diary:diary_list' %}">日記の一覧</a></h2> {% endblock %} |
まず index.html の冒頭にある、 {% extends 'base.html' %} というコードにより、base.html を継承しています。
そして、 {% block content %} と {% endblock %} で囲まれた内容が、base.html の content ブロックに追加されます。
ちなみに、以下のコードが、これまでの index.html です。
1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>MyDiaryApp</title> </head> <body> <h1>Diary App by Django</h1> <h2><a href="{% url 'diary:diary_create' %}">日記の投稿</a></h2> <h2><a href="{% url 'diary:diary_list' %}">日記の一覧</a></h2> </body> </html> |
コードの量が、約半分になっていますね。
<body>タグ以外の内容が、全て親テンプレートに吸収されています。
テンプレートの継承を利用すると、「その画面に固有の要素」が浮き彫りになりますので、保守性がぐっと上がります。
他のテンプレートも継承利用へ改修
他の全てのテンプレートも、テンプレートの継承を利用した形に改修してみましょう。
見本として、「diary_create.html」と「diary_update.html」を、テンプレートを利用した形式に改修したものを記載します。
diary_create.html テンプレート継承バージョン
1 2 3 4 5 6 7 8 9 | {% extends 'base.html' %} {% block content %} <h1>日記の作成</h1> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">投稿</button> </form> {% endblock %} |
diary_update.html テンプレート継承バージョン
1 2 3 4 5 6 7 8 9 | {% extends 'base.html' %} {% block content %} <h1>日記の編集</h1> <form method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="保存"> </form> {% endblock %} |
class属性の付け方
ここからは、画面のデザインを整えていくことにフォーカスしていきます。
画面デザインを整える方法として代表的なものが、Bootstrap を利用すること。
Bootstrap では、見た目を変えたい html 要素に適切なクラスを設定することで、自動的にプリセットデザインが反映されます。
Django でも、テンプレート内部の html 要素に、従来通り class 属性を与えてあげれば OK です。
ただし、いくつかの要素には問題があります。
問題の例
例えばフォームです。
今回の記事で学んだ通り、フォームは Django テンプレート言語の変数を利用して、 { form } といった形で表現されます。
この変数に対して、 { form class="form-class" } としてもダメです…。
Django において、フォームを定義しているのは、forms.py に定義されたフォームクラス。
このフォームクラスを変更して、class 属性を追加する方法を学びましょう!
formクラスにclass属性を追加しよう
diary ディレクトリ内の forms.py には、DiaryForm クラスが定義されています。
この DiaryForm クラスを改修して、以下の3つに class 属性を付与します。
- date
- title
- text
DiaryForm クラスを、以下のように変えてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 | from django import forms from .models import Diary class DiaryForm(forms.ModelForm): class Meta: model = Diary fields = ('date', 'title', 'text') widgets = { 'date': forms.DateInput(attrs={'class': 'form-control'}), 'title': forms.TextInput(attrs={'class': 'form-control'}), 'text': forms.TextInput(attrs={'class': 'form-control'}), } |
ポイントはwidget
ポイントは、 Meta クラス内部に定義された、widget というフィールドです。
この widget は、辞書型のデータを持っています。
キーが form のフィールド値、バリューがフォームの種類を定める、ウィジェットと呼ばれるクラスです。
このウィジェットの種類や、クラス引数を変えることにより、テンプレートに埋め込まれるフォームの種類や属性値が変わります。
attrs というクラス引数を見ると、class をキーとして、バリューが form-control となっていますね。
これにより、form-contol という class 属性が、各フォームに付与されます。
この改修を終えたら、一度 Django プロジェクトを起動してみましょう。
Chromeデベロッパーツールで確認
Chrome デベロッパーツールで、日記投稿画面の実装を確認すると、以下のようになっているはずです。

これでフォームに、class を設定することができました。
widget は、class を追加するだけでなく、フォームの大きさを変えたりフォームの種類を変えたりなど、フォームに関する様々な調整が可能です。
例えば、title のウィジェットを TextInput から Textarea に変更すると、以下のように html のテキストエリアが作成されます。

ウィジェットを介したclass設定には問題も…
ウィジェットを介して、class を設定する方法を学びましたが、実はこの方法には少し問題があります。
例えば、フォームに対する class 属性は、forms.py の中に定義されています。
ところが、それ以外の div タグなどの class 属性は、html ファイルの中に記述されているのです。
これでは、保守性が落ちてしまいます。
やはり class 属性ぐらいは、html ファイルの中で、全て宣言したいところ…。
これを実現するには、「django-widget-tweak」というライブラリを使えば OK です。
django-widget-tweak を利用してclass属性を追加しよう
django-widget-tweaks というライブラリを利用すれば、テンプレート内部で class 属性を定義することができます。
【GitHub:django-widget-tweaks】
https://github.com/jazzband/django-widget-tweaks
それでは、バージョン1.4.8をインストールして利用してみましょう。
terminal で、以下のコマンドを実行します。
1 | pip install django-widget-tweaks==1.4.8 |
pip show django-widget-tweaks を実行すると、以下のような出力が得られます。
1 2 3 4 5 6 7 8 | Name: django-widget-tweaks Version: 1.4.8 Summary: Tweak the form field rendering in templates, not in python-level form definitions. Home-page: https://github.com/jazzband/django-widget-tweaks Author: Mikhail Korobov Author-email: kmike84@gmail.com License: MIT license 〜省略〜 |
MIT license であるため、ライセンスに従えば商用利用も OK です。
インストールが完了した後は、config ディレクトリの中にある settings.py を開き、widget_tweaks アプリを追加します。
1 2 3 4 5 6 7 8 9 10 | INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'diary', 'widget_tweaks', # 追加 ] |
このアプリを利用することで、例えば以下のような記述で、class 属性を付与することが可能です。
1 | {{ form.date | add_class:'form-control' }} |
次の章では、「django-widget-tweaks」と「bootstrap」を併用して、画面の装飾を行なっていきましょう!
Bootstrap4を利用するための準備
それでは、bootsttrap を利用して、画面装飾を行なっていきましょう。
CDN で Bootstrap を利用することもできます。
ただ Django では、3rd パーティの Django アプリを介して、bootstrap を利用することも可能です。
django-bootstrap4をインストール
以下のコマンドを実行し、django-bootstrap4 をインストールしましょう!
1 | pip install django-bootstrap4==2.3.1 |
pip show django-bootstrap4 を実行すると、以下のような出力が得られます。
1 2 3 4 5 6 7 8 | Name: django-bootstrap4 Version: 2.3.1 Summary: Bootstrap support for Django projects Home-page: https://github.com/zostera/django-bootstrap4 Author: Dylan Verheul Author-email: dylan@zostera.nl License: BSD-3-Clause 〜省略〜 |
BSD-3-Clause ライセンスであるため、商用利用の際には、著作権表示や免責事項等の表示に注意しましょう。
settings.pyにbootstrap4アプリを追加
インストールが完了したら、django-widget-tweaks と同様に、settings.py に bootstrap4 アプリを追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 | INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'diary', 'bootstrap4', # 追加 'widget_tweaks', ] |
settings.pyのTEMPLATESを編集
また、settings.py の TEMPLATES の編集も必要です。
TEMPLATES の builtins に、コードを追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'), ], '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', ], 'builtins': [ 'bootstrap4.templatetags.bootstrap4', # 追加 ], }, }, ] |
この記述により、django-bootstrap4 が提供する組み込み(built in)タグを、利用できるようになります。
テンプレートの編集
では、テンプレートの編集に移っていきます。
まずは、親テンプレートである base.html の先頭に、bootstrap を利用するための記述を加えます。
1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html> <html lang="jp"> {% bootstrap_css %} <!-- 追加 -- > <head> <meta charset="UTF-8"> <title>MyDjangoApp</title> </head> <body> {% block content %} {% endblock %} </body> </html> |
これで、base.html を継承した全テンプレートで、bootstrap を利用することができます。
diary_create.htmlを編集
続いて、diary_create.html を、以下のように編集しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | {% extends 'base.html' %} {% load widget_tweaks %} {% block content %} <h1>日記の作成</h1> <form method="post"> {% csrf_token %} <div class="form-group"> <label>{{ form.date.label }}</label> {{ form.date | add_class:'form-control col-2' }} </div> <div class="form-group"> <label>{{ form.title.label }}</label> {{ form.title | add_class:'form-control col-2' }} </div> <div class="form-group"> <label>{{ form.text.label }}</label> {{ form.text | add_class:'form-control col-2' }} </div> <button type="submit" class="form-control col-1">投稿</button> </form> {% endblock %} |
このコードには、ポイントが2つあります。
ポイント1:{% load widget_tweaks %}
まず1つ目が、2行目にある {% load widget_tweaks %} です。
この記述により、django-widget-tweaks の機能が、テンプレートの中で利用できるようになります。
load タグを利用するなら、テンプレート1つ1つに宣言が必要となるので注意して下さい。
ちなみにこのあたりの内容は、ライブラリの実装も関わってくるため、ここでは深入りはしません。
ポイント2:add_class
2つ目のポイントが、add_class です。
widget-tweak の add_class を利用して、各フォーム値にお手軽にクラス属性を付与しています。
厳密には、Django のフィルターという機能が併用されています。
また、上記テンプレートのコードは、bootstrap のフレームワークを意識してみました。
form-group と form-control を設定し、見栄えも考えて、col クラスの設定も行なっています。
Djangoプロジェクトの動作確認
長くなってしまいましが、ここまでの編集が終わったら、Django プロジェクトを起動してみましょう。
日記投稿画面は、以下のようになります。

第7回へつづく!
今回の記事では、Django テンプレートに、様々な工夫を施しました。
今回の記事のポイントは、以下の4つです。
- Django テンプレート言語の代表的な機能として「変数」と「タグ」がある
- テンプレートの継承を利用すれば、テンプレートの作成が楽に!
- class 属性を追加するには、form クラスを扱う方法と django-widget-tweak を利用する方法がある
- django-bootstrap を利用することで、Django アプリとして bootstrap を利用することができる
次回は、Django アプリのテストの実装方法を学びます。
次回もお楽しみに!
第7回はこちら!
こちらの記事もオススメ!
書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ライトコードの日常12月 1, 2023ライトコードクエスト〜東京オフィス歴史編〜
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン