スキルアップ

DjangoのテンプレートでデータをHTMLに埋め込む

はじめに

DjangoでWebアプリを作るとき、
ユーザーの目に見える部分が テンプレート(Template) です。

  • HTMLを書くだけじゃダメなのか
  • views.pyとの役割分担がよく分からない

DjangoやWebアプリそのものに慣れていないと
テンプレートの役割や重要性がいまいちわかりにくいですよね。

実際、DjangoのTemplateは単なるHTMLではありません。

データベースから取得した情報や、Viewで処理した内容を
{{ }}{% %} という独自のタグを使って埋め込む仕組み
を持っています。

これにより、動的に変わるWebページを
簡単に作ることが可能です。

例えば、ブログの記事一覧を作りたい場合、

  • Viewが「記事データ」を集めてTemplateに渡す
  • Templateでは渡された「記事タイトルや本文」
    のデータをループで並べて表示する

この役割分担によって、処理とデザインを
きれいに切り分けることができ、
保守性の高いアプリ開発が実現します。

この記事では、私が学習した内容をもとに
Templateの基本的な役割から、
つまずきやすいエラー、実際のコード例などを
まとめていきます。

この記事はこんな方におすすめです!

  • DjangoのTemplateが、
    ただのHTMLと何が違うのか知りたい方
  • Viewとの連携方法があいまいな方
  • 自分のWebアプリの画面に、
    データを埋め込んで作ってみたい方


第1章:テンプレートの役割

Djangoのテンプレートは、単なるHTMLファイルではありません。

アプリ全体の中では、ユーザーに見せる最終的な画面を担う
重要な役割を果たしています。

ViewやModelと連携することで、
データを見やすく整えて表示する仕組みを持っています。


1. MTVモデルの中での位置づけ

Djangoは、MTVモデルという仕組みに基づいています。

  • Model
    データベースとのやりとりを担当
  • View
    処理の流れを決める
    (データを集めてどのテンプレートを使うか指示)
  • Template
    ユーザーに見せる画面を生成する

テンプレートは渡されたデータの中身を
そのまま見せるのではなく、
わかりやすく、きれいに表示する役割を持っています。


2. データをHTMLに埋め込む

テンプレートの最大の特徴は、
Djangoテンプレート言語 を使ってデータを埋め込めることです。

簡単な例として、Viewから渡したデータを
テンプレートに表示する場合、

# views.py
def greet_view(request):
    context = {"name": "太郎"}
    return render(request, "greet.html", context)
<!-- greet.html -->
<p>こんにちは、{{ name }}さん!</p>

ここで {{ }} といテンプレートタグを使うことで、
データの内容によって、動的に変化するページを
作れるようになります。

また、 {% %} を使うことで、
HTMLの中で繰り返しや条件分岐を記述できます。

繰り返し:

<ul>
{% for post in posts %}
    <li>{{ post.title }}</li>
{% endfor %}
</ul>

条件分岐:

{% if user.is_authenticated %}
    <p>{{ user.username }}さん、ようこそ!</p>
{% else %}
    <p>ログインしてください。</p>
{% endif %}

これにより、柔軟に表示内容を柔軟に変えることができます。

また、ポートフォリオ作成では、
より業務に近いWebアプリのような画面
を作成することにもつながります。


3. テンプレートの要点

  • Djangoにおける画面表示担当であり、
    ユーザーにデータを届ける最終工程
  • Djangoテンプレート言語を使うことで、
    変数埋め込み・繰り返し・条件分岐が可能
  • ViewやModelと役割分担し、
    処理とデザインを分けることで保守性が高まる
  • Templateは、アプリ全体を
    ユーザーにとって使いやすく整える存在

第2章:つまずきやすいポイント

テンプレートはDjangoの中でも画面を作る部分を担うため、
Webアプリの動作確認時にも触れる機会も多いです。

その分、

  • 画面が表示されない
  • 変数が出てこない

などのトラブルにもよく直面します。

ここでは私が学習時につまずいたポイントを整理して紹介します。


1. TemplateDoesNotExistエラー

ブラウザで画面にアクセスすると
TemplateDoesNotExist と表示されるエラーです。

主な原因として、

  • テンプレートファイルが正しい場所にない
  • templates/ フォルダの構成が間違っている
  • settings.pyTEMPLATES['DIRS']
    にパスを設定していない

これを解消するために、見直したいポイントは

  • アプリごとに
    templates/アプリ名/ファイル.html
    の構成にする
  • render() で呼ぶときは、
    アプリ名を含めたパスを書く
    return render(request, "users/signup.html")

テンプレートファイルの配置場所と、
Viewからのパス指定が合っているか
をまず確認することが基本ですが重要です。


2. 変数が表示されない

Viewからデータを渡しているのに、画面表示時に出てこない。
これもよくある不具合です。

単純ではありますが、誤りの例として、

# views.py
def greet_view(request):
    context = {"username": "太郎"}
    return render(request, "greet.html", context)
<!-- greet.html -->
<p>こんにちは、{{ name }}さん!</p>

ここでは、Viewで渡しているキーは username なのに、
テンプレート側で name を呼び出しているため、
何も表示されません。

解消するために確認したいポイントとして、

  • View側のキー名とテンプレート側の変数名を
    一致させる
  • デバッグ時で、
    変数の値を設定していない場合などは
    {{ 変数|default:"値なし" }}
    と書くと確認しやすい

3. 静的ファイル(CSSや画像)が反映されない

テンプレートで見た目を整えようとしたときに、
HTMLと同様にCSSなど静的ファイルの読み込みが可能です。
そのCSSや画像が表示されないトラブルもよくあります。

主な原因としては、

  • {% load static %} を書き忘れている
  • ファイルを static/ フォルダに置いていない
  • 本番環境で collectstatic をしていない

静的ファイルのテンプレートでの読み込みの
正しい書き方は以下です。

{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<img src="{% static 'images/logo.png' %}" alt="ロゴ">

Djangoでは、静的ファイルを扱うために
static/ フォルダ を準備しておき、
その配下に、CSSなどのファイルを配置することで
Djangoが対象の静的ファイルを認識できるようになります。

詳しくは次の章でまとめます。


4. forループやif文が効かない

テンプレートの構文はシンプルですが、
よくミスするのが タグの閉じ忘れ です。

これは、テンプレートに限った話ではないですが
HTML同様に開始、終了のタグはペアになるように
注意しましょう。

HTMLタグは一部、終了タグの記載漏れでも
ブラウザ側で補完され、挙動に問題なく見える場合もあります。

しかし、Djangoのテンプレート言語でのタグを利用する場合は
必ず、このセットに漏れがないようにしましょう。

誤り例としては、

{% for post in posts %}
  <p>{{ post.title }}</p>
<!-- {% endfor %} がない -->

上記のような誤りの場合、正しい書き方として、

{% for post in posts %}
  <p>{{ post.title }}</p>
{% endfor %}

5. ハードコーディングでのリンク切れ

テンプレートとurls.pyの関係を曖昧なまま
Webアプリを作成していると、
画面遷移のためのリンクを作るときに、
次のように書いてしまいがちです。

<a href="/signup/">登録</a>

一見問題なく見えます。
また、実際にこのURLがurls.py
マッピングされていれば問題ありません。

しかし、マッピングのためのURLを後から変更すると
リンクがすべて壊れてしまいます。

これらの問題を発生しないようにするためにも、
URLのハードコードは行わず、
必ず urls.pyname を使って参照するようにしましょう。

<a href="{% url 'users:signup' %}">登録</a>

第3章:実際のテンプレートの定義

テンプレートは、ユーザーに見せる最終的な画面を作る場所です。

押さえるべきテンプレートの定義の要点をまとめます。
これらは基本となりますが、
Webアプリの開発では非常に利用する内容です。


1. 変数の埋め込み

Viewから渡したデータは、
テンプレートで {{ }} を使って表示できます。
Viewとテンプレートの変数名が一致していることが重要です。

# views.py
def greet_view(request):
    context = {"name": "太郎"}
    return render(request, "greet.html", context)
<!-- greet.html -->
<p>こんにちは、{{ name }}さん!</p>

2. 繰り返し処理

複数のデータを一覧表示したい場合、{% for %} を使います。
forループは一覧ページや、
複数要素をまとめて表示する時の基本パターンです。

# views.py
def post_list(request):
    posts = [
        {"title": "記事1", "author": "山田"},
        {"title": "記事2", "author": "佐藤"},
    ]
    return render(request, "post_list.html", {"posts": posts})
<!-- post_list.html -->
<ul>
{% for post in posts %}
    <li>{{ post.title }}({{ post.author }})</li>
{% endfor %}
</ul>

3. 条件分岐

テンプレートでは {% if %} を使って、
条件によって表示を変えることができます。

{% if user.is_authenticated %}
    <p>{{ user.username }}さん、ようこそ!</p>
{% else %}
    <p>ログインしてください。</p>
{% endif %}

例えば、Viewからの渡されたデータで、
値がある場合のみ画面に表示するなどの制御に便利です。

また、指定の要素を判定して、対象のCSSのスタイルを当てるなど
画面の表示での様々な条件分けにも応用できます。


4. テンプレートの継承

大規模なアプリでは、画面数も相当数になるので
共通部分(ヘッダーやフッターなど)を毎回書くのは非効率です。

そこで使うのが テンプレート継承 です。

Webアプリなどでは、サイトのヘッダー部分は
常に共通として見栄えを統一することも多いため
ベースとなるテンプレートを準備し、各画面に引き継がせることで
それぞれの画面で統一感のある見た目に整えることが可能です。

ベーステンプレート(base.html)の例として、

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}My Site{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
    <header>
        <h1>共通ヘッダー</h1>
    </header>
    <main>
        {% block content %}{% endblock %}
    </main>
    <footer>
        <p>フッター</p>
    </footer>
</body>
</html>

そして、各画面となるテンプレートでは、
ベーステンプレートの{% block content %}の部分のみ
を作成するのが基本となります。

{% extends "base.html" %}

{% block title %}トップページ{% endblock %}

{% block content %}
    <h2>記事一覧</h2>
    <p>ここに記事を表示します。</p>
{% endblock %}

5. 静的ファイルの利用

画面デザインを整えるために、
CSSや画像などの静的ファイルを読み込みます。

その際の、Webアプリのフォルダ構成として、
staticフォルダを準備し、
その配下に静的ファイルを配置するようにします。

project_root/
 └── static/
      ├── css/
      │    └── style.css
      └── images/
           └── logo.png

テンプレートで、読み込む際には

{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<img src="{% static 'images/logo.png' %}" alt="ロゴ">

{% load static %} を忘れると
Djangoが静的ファイルを配置しているフォルダを見つけられず
読み込めないので、必ずテンプレートの先頭に書きましょう。


6. URLの逆引き

リンクを作るときは、ハードコーディングせずに
{% url %} を使います。
URLが変更されても、urls.pyのnameが
一致していればリンクは壊れません。

<a href="{% url 'users:signup' %}">ユーザー登録</a>
<a href="{% url 'blog:post_list' %}">記事一覧</a>

7. フィルターでデータを整形

Djangoのテンプレートでは
フィルター を使って表示内容を加工できます。

<p>投稿日: {{ post.created_at|date:"Y年m月d日" }}</p>
<p>本文: {{ post.content|truncatechars:20 }}</p>
  • date:"Y年m月d日" → 日付を整形
  • truncatechars:20 → 文字数を20文字に制限

見た目を調整するときに、バックエンド側で加工せずに
テンプレート側で適用できるため便利な機能です。


第4章:まとめ

ここまで、Djangoの テンプレートについて
私が学習した内容をもとに基本を中心にまとめていきました。

要点としては、

  • Templateが、ユーザーに見せる画面を担う役割
  • データを変数として埋め込み動的な画面にできる
  • 繰り返し、条件分岐、継承等で
    柔軟に画面を定義できる

テンプレートは、ただのHTMLではありません。

ViewやModelと役割を分けて設計することで、
保守性が高く、使いやすいWebアプリを作ることができます。

テンプレートを押さえると、
見た目を動かす楽しさを実感しやすいです。

また、バックエンド側で加工したデータなどの
整理のしやすさも利点としてあります。

私も現在、Djangoで
ポートフォリオ用のWebアプリを作成しています。

また、なにか気づきがあれば記事にしていこうと思います。

  • この記事を書いた人

ニコ

元美容師、未経験からIT業界へ転職。
現在はIT企業でWEBシステム、
汎用業務システムのSEとして在籍!
趣味の筋トレ、スキルアップや副業など
社会人の総合量を磨く情報を発信。
170cm / 65kg / ライフタイムナチュラル

-スキルアップ