パート2
テンプレートを使う

テンプレートを使う

Django を構成する 3 つの要素は、モデル、ビュー、テンプレートです。 この節では、テンプレートの使い方を説明します。

前の節では、show_hello という関数を定義し、「Hello, world!」という文字列を返すようにしました。

accounts/views.py
from django.http import HttpResponse
 
def show_hello(request):
    return HttpResponse("Hello, World!")

このように、関数の中で文字列を返すと、その文字列がブラウザに表示されます。 同様にして HTML を返すと、その HTML がブラウザに表示されます。 HTML を返すには、文字列の中に HTML を書きます。

accounts/views.py
from django.http import HttpResponse
 
def show_hello(request):
    return HttpResponse("<h1>Hello, World!</h1>")

しかし、すべてのページで HTML を文字列として Python のコードに書くのは大変です。 視認性が悪くなりメンテナンスが大変になりますし、何より HTML を Python のファイルの中に書かなければいけないので IDE(統合開発環境)による補完といった便利な機能が使えません。

そこで Django では、HTML を別のファイルに書き、それを読み込んで返すようにします。 この HTML を書いたファイルのことを「テンプレート」と呼びます。

このドキュメントでは、HTML と CSS についての説明は省略します。 HTML と CSS については、他のドキュメントを参照してください。 mdn web docs (opens in a new tab) は、Web 開発について網羅的に説明していておすすめです。

テンプレートを作る

今、ディレクトリの構成は次のようになっているはずです。

  • db.sqlite3
  • manage.py
  • poetry.lock
  • pyproject.toml
  • このうち、templates というディレクトリの中にテンプレートを作っていきます。

    これは、settings.py の中に書かれている TEMPLATES という設定によって決まっています。

    mysite/settings.py
    TEMPLATES = [
        {
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            "DIRS": [BASE_DIR, "templates"],
            ...
        },
    ]

    まずは、templates/base.html というファイルを作ります。

    templates/base.html
    <!doctype html>
    <html lang="ja">
        <head>
            <meta charset="UTF-8" />
            <title>{% block title %}{% endblock %}</title>
        </head>
        <body>
            {% block content %}{% endblock %}
        </body>
    </html>

    HTML に馴染みのある人にとっては、この HTML はなんの変哲もないものに見えるかもしれません。

    しかし、この HTML には Django のテンプレート言語というものが使われています。

    {% block title %}{% endblock %} というのは、テンプレートの中に別のテンプレートを埋め込むためのものです。 この {% block title %}{% endblock %} という部分を「ブロック」と呼びます。

    このブロックの中には別のテンプレートを埋め込むことができ、このようにして動的な HTML を作ることができます。

    なおこのプロジェクトでは、base.html はその名の通り、他のテンプレートの土台となるテンプレートとして位置付けています。


    次に、templates/accounts/hello.html というファイルを作ります。

    templates/accounts/hello.html
    {% extends "base.html" %} {% block title %}Hello, World!{% endblock %} {% block
    content %}
    <h1>Hello, World!</h1>
    {% endblock %}

    このテンプレートは、base.html を継承しています。 {% extends "base.html" %} というのは、base.html を継承するという意味です。 これにより、base.html に記述した各ブロックに対応する部分を埋め込むことができます。

    {% block title %}Hello, World!{% endblock %} というのは、base.htmltitle というブロックを埋め込むという意味です。 {% block content %}...{% endblock %} というのは、base.htmlcontent というブロックを埋め込むという意味です。

    このようにして、base.html に記述した HTML の一部を、別のテンプレートから埋め込むことができます。

    テンプレートを使う

    テンプレートを使うには、render という関数を使います。

    accounts/views.py
    from django.http import HttpResponse
    from django.shortcuts import render
     
     
    def show_hello(request):
        return render(request, "accounts/hello.html")

    render は、第 1 引数に request を、第 2 引数にテンプレートのパスを受け取ります。 そして、そのテンプレートを読み込んで、その内容を HttpResponse に変換して返します。

    render は、テンプレートの中に変数を渡すこともできます。 その場合は、第 3 引数以降に渡したい変数をキーワード引数として渡します。

    accounts/views.py
    from django.http import HttpResponse
    from django.shortcuts import render
     
     
    def show_hello(request):
        return render(request, "accounts/hello.html", name="World")
    templates/accounts/hello.html
    {% extends "base.html" %} {% block title %}Hello, {{ name }}!{% endblock %} {%
    block content %}
    <h1>Hello, {{ name }}!</h1>
    {% endblock %}

    テンプレートでは、{{ name }} というように変数を使うことができます。

    実際にブラウザで表示してみると、{{ name }} の部分が World に置き換わっていることがわかります。

    {{}} が口髭(mustache)に似ていることから、マスタッシュ構文と呼ぶこともあります。

    まとめ

    • Django では、テンプレートを使って HTML を作る
    • ビューで動的な処理を行い、表示させる情報を変数としてテンプレートに渡す

    なお、Django テンプレートの構文は他にもたくさんあります。 詳しくは、リファレンス (opens in a new tab)を参照してください。