Python Django入門 初めの1歩からWEBアプリ作成までの流れ その3 テンプレートタグの基礎1

みなさんこんにちは、ZeroTerasu(@ZeroTerasu)です。

Djangoでは、アプリ内の”templates”フォルダ内にhtmlファイルを作成し、そのhtmlファイルにviews.pyで作成された様々な情報を渡す場面が多くあります。

ここでは、”templates”フォルダ内のhtmlファイル内で使用されるテンプレートタグについて解説とそれに合わせたviews.pyのコードの記述方法を解説してきます。

  1. テンプレートの役割:HTMLの一部だけを書き換える機能
    1. <テンプレートを組み立てる3種類の要素>
      1. 変数:{{ 変数名 }}、タグ:{% タグ名 %}、フィルタ:{{ 値 | フィルタ名 }}
  2. 例1:ナビゲーションメニュー・ヘッダー・フッター部分(テンプレート)をパーツとして独立させる
    1. 手順1:各パーツを個別のhtmlファイルとして作成する。
    2. 手順2:各ウェブページでそれぞれのパーツを読み込む ※includeタグを用いる。
    3. includeタグ:{% include “パーツのテンプレート名” %}
    4. 手順3:CSSを設定する。
    5. 例:<navbarの作成>
    6. 例:<footterの作成>
      1. ※{% include %}タグを使って呼び出すhtmlファイルに対して、コンテキストを引き渡す方法
    7. 手順3:CSSの設定をする。
      1. 手順3-1:「static」フォルダの作成 (apps/static)
      2. 手順3-2:「style.css」の作成 (apps/static/style.css)
      3. 手順3-3:htmlファイルへCSSを読み込ませる
      4. 手順3-4:settings.pyにstaticフォルダパスを記述
  3. 例2:ベースとなるhtmlファイル(base.html)を作成して新しいページを作成する。
    1. extendsタグ:{% extends “ベースとなるテンプレート名” %}
    2. blockタグ:{% block ブロック名 %}個別ページ内容{% endblock %}
  4. 例3:usernameを表示させる。
    1. やりたいこと:views.pyからテンプレート(htmlファイル)に値を渡したい
    2. 変数名タグ:{{ 変数名 }}
  5. 例4:テンプレート(htmlファイル)に数字表示変更・リスト作成
    1. 例:アドレス帳に登録されている人数と人名をhtmlファイルに表示する。
      1. 手順①:元々登録されている情報を基にhtmlファイルを作成する。
      2. 手順②:変更を加える箇所を{{ 変数名 }}タグで置換する。
      3. 手順③:views.pyで変更内容を定義する。
    2. テンプレート(htmlファイル)の数字表示変更の例
    3. テンプレート(htmlファイル)のリスト作成の例
      1. リスト作成方法
    4. 現在時刻を表示する = {% now %}の活用
  6. 例5:アクセスユーザーの種類によってユーザー名を表示し分ける
    1. TIME_ZONEの編集
    2. footerの年を変更

テンプレートの役割:HTMLの一部だけを書き換える機能

<テンプレートを組み立てる3種類の要素>

変数:{{ 変数名 }}、タグ:{% タグ名 %}、フィルタ:{{ 値 | フィルタ名 }}

(要素) (文法)
・変数{{ 変数名 }}
・タグ{% タグ名 %}
・フィルタ  {{ 値 | フィルタ名 }}

例1:ナビゲーションメニュー・ヘッダー・フッター部分(テンプレート)をパーツとして独立させる

ナビゲーションメニュー・ヘッダー・フッター等各ページで共通するページをそれぞれ独立したパーツとして作成して、各ページではそれぞれのパーツを都度読み込む方法を解説します。

これによって、それぞれのパーツに変更が生じた際に、全ページ編集の必要がなくなり、各パーツを編集すれば全ページに変更が適用されるようになりますので、メンテナンス性向上に繋がります。

手順は以下の通りです。

手順1:各パーツを個別のhtmlファイルとして作成する。

手順2:各ウェブページでそれぞれのパーツを読み込む ※includeタグを用いる。

includeタグ:{% include “パーツのテンプレート名” %}

手順3:CSSを設定する。

例:<navbarの作成>

手順1:各パーツを個別のhtmlファイルとして作成する。
下記ディレクトリのように「_navbar.html」を作成する。
(apps/templates/_navbar.html)

<div class="navbar">
<a href="/">ホーム</a>
<a href="/about">私たちについて</a>
</div>
手順2:各ウェブページでそれぞれのパーツを読み込む ※includeタグを用いる。
(apps/templates/index.html)
<html>
<head>
</head>
<body>
{% include "_navbar.html" %}
<h1>自己紹介</h1>
</body>
</html>

例:<footterの作成>

手順1:各パーツを個別のhtmlファイルとして作成する。
下記ディレクトリのように「_footer.html」を作成する。

(apps/templates/_footer.html)
<div>
<p>Copyright 2015-</p>
</div>
手順2:各ウェブページでそれぞれのパーツを読み込む ※includeタグを用いる。
(apps/templates/index.html)
<html>
<head>
</head>
<body>
{% include "_navbar.html" %}
<h1>自己紹介</h1>
{% include "_footer.html" %}
</body>
</html>

※{% include %}タグを使って呼び出すhtmlファイルに対して、コンテキストを引き渡す方法

{{% include ‘テンプレートhtml’ with 変数名=”任意の値” %}}

※{% include %}タグを使って呼び出すhtmlファイルに対して、コンテキストを引き渡す方法
(apps/templates/_footer.html)
<!-- 「年」の部分を{{変数名}}タグで置換する。呼び出す側のhtmlテンプレートから{{year}}に値が引き渡されるようにする。 -->
<div>
<p>Copyright {{year}}-</p>
</div>
(apps/templates/index.html)
<!--  -->
<html>
<head>
</head>
<body>
{% include "_navbar.html" %}
<h1>自己紹介</h1>
{% include "_footer.html" with year="2020" %} <!-- "2020"が_footer.htmlの{{year}}に引き渡される -->
</body>
</html>

手順3:CSSの設定をする。

次に、CSSの設定をします。手順は以下の通りです。

手順3-1:「static」フォルダの作成 (apps/static)

手順3-2:「style.css」の作成 (apps/static/style.css)

手順3-3:htmlファイルへCSSを読み込ませる

手順3-4:settings.pyにstaticフォルダパスを記述

手順3-2:「style.css」の作成 (apps/static/style.css)
(apps/static/style.css)
.navbar{
background: pink;
}
手順3-3:htmlファイルへCSSを読み込ませる
(apps/templates/index.html)
{% load static %} #<=忘れがちなので要注意
<html>
<head>
<link rel="stylesheet" href="{% static 'style.css' %}">
</head>
<body>
{% include "_navbar.html" %}
<h1>自己紹介</h1>
{% include "_footer.html" %}
</body>
</html>
手順3-4:settings.pyにstaticフォルダパスを記述
STATIC_URL = 'static/'
import os
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

#デフォルトでSTATIC_URL = '/static/'となっているのでこれは触らず,その下に上記を追記します。
#osライブラリのインポートが必要な場合は、上記のようにimport osを記述
#先程作成したstaticディレクトリの場所を教えてあげるようなイメージです。

例2:ベースとなるhtmlファイル(base.html)を作成して新しいページを作成する。

まず、ベースとなるhtmlを作成し、次にそれを継承(extends)して新しいページを作成します。そして、下記コードのようにblockタグで挟まれた部分だけ個別のページ毎に変化させることができます。

extendsタグ:{% extends “ベースとなるテンプレート名” %}

blockタグ:{% block ブロック名 %}個別ページ内容{% endblock %}

<テンプレートを共通化したい>
extendsタグとblockタグ

{% extends "ベースとなるテンプレート名" %}

{% block ブロック名 %}
この中身は使う側で上書きできる
{% endblock %}

まずは、各ページのベースとなるbase.htmlをtemplatesフォルダ内に作成します。

base.htmlの作成 (apps/templates/base.html)
{% load static %}
<html>
<head>
<link rel="stylesheet" href="{% static 'style.css' %}">
</head>
<body>
{% include "_navbar.html" %}

{% block main %}
コンテンツがありません。
{% endblock %}

{% include "_footer.html" %}
</body>
</html>

次に、個別ページを作成していきます。index.htmlというファイル名でbase.htmlが保存されているフォルダと同じtemplatesフォルダに作成します。

(apps/templates/index.html)
{% extends "base.html" %}
{% load static %}

{% block main %}
<h1>ホーム</h1>
<img src="{% static 'welcome.jpg' %} />
{% endblock %}

• 画像を読み込むためには、staticフォルダ内に画像を用意しておく必要がある。
• {% load static %} は、base.htmlで設定していても、index.htmlでも設定する必要がある。

例3:usernameを表示させる。

ここからは、具体的にviewからテンプレート(htmlファイル)に値を渡す方法について説明していきます。

やりたいこと:views.pyからテンプレート(htmlファイル)に値を渡したい

views.pyに「get_context_data」という関数を定義します。

この関数の中の「context」(コード内では、変数ctxtと定義。以下、「context」=「ctxt」とします。)を使って値を渡すことが出来ます。

「ctxt」の要素を「get_context_data」内で変更を加えて、変更後の「ctxt」をhtmlファイルに渡すことで変更内容がhtmlファイルに反映されます。

また、「ctxt」の各要素は、テンプレート(htmlファイル)の中では{{ 変数名 }}で表示できます。

変数名タグ:{{ 変数名 }}

まずは、テンプレートを作成します。

テンプレートに{{ 変数名 }}を定義
(apps/templates/index.html)

{% extends "base.html" %}
{% load static %}

{% block main %}
<h1>{{ username }}さんこんにちは</h1>
<img src="{% static 'welcome.jpg' %} />
{% endblock %}

次に、views.pyを作成します。

views.pyに「get_context_data」を定義する。
(apps/views.py)
from django.views.generic import TemplateView

class IndexView(TemplateView):
template_name = "index.html"

def get_context_data(self):
ctxt = super().get_context_data()
ctxt["username"] = "太郎"
return ctxt

class AboutView(TemplateView):
template_name = "about.html"

• ctxt:開発者の間では一般的な記法。辞書型。
• super():TemplateViewが用意しているUserを規定する変数
• super().get_context_data():TemplateViewが用意しているUserを表す変数からデータを取得している。

例4:テンプレート(htmlファイル)に数字表示変更・リスト作成

例:アドレス帳に登録されている人数と人名をhtmlファイルに表示する。

元々アドレス帳に登録されている件数と分類を表示し、その後アドレス帳に追加した後の情報をhtmlファイルに表示したいと思います。

手順としては下記のようになります。

手順①:元々登録されている情報を基にhtmlファイルを作成する。

手順②:変更を加える箇所を{{ 変数名 }}タグで置換する。

手順③:views.pyで変更内容を定義する。

元々登録されている情報
アドレス帳登録件数:123456名
アドレス帳分類:家族、仕事、趣味

追加後に登録されている情報
アドレス帳登録件数:12345678名
アドレス帳分類:家族、仕事、趣味、町内会、役所、携帯ショップ

下記の例では、まずアドレス帳登録件数の変更のコードを記述します。

テンプレート(htmlファイル)の数字表示変更の例

手順①:address.htmlに元々の登録内容を入力する
(apps/templates/address.html)
{% extends "base.html" %}
{% load static %}

{% block main %}
<h1>アドレス帳</h1>
<h2>登録件数</h2>
<p>これまでに123456件のアドレスが登録されていました。</p>
<h2>分類</h2>
<ul>
<li>家族</li>
<li>仕事</li>
<li>趣味</li>
</ul>
{% endblock %}
手順②:address.htmlの変更を加える箇所を{{ 変数名 }}タグで置換する。
(apps/templates/address.html)
{% extends "base.html" %}
{% load static %}
{% load humanize %}

{% block main %}
<h1>アドレス帳</h1>
<h2>登録件数</h2>
<p>これまでに{{ num_registration|intcomma }}件のアドレスが登録されていました。</p>
<h2>分類</h2>
<ul>
<li>家族</li>
<li>仕事</li>
<li>趣味</li>
</ul>
{% endblock %}
• humanizeはsetting.py => INSTALLED_APPSに追加する必要がある。
 'django.contrib.humanize'
手順③:views.pyで変更内容を定義する。
(apps/views.py)
from django.views.generic import TemplateView

class AboutView(TemplateView):
    template_name = "address.html"

def get_context_data(self):
    ctxt["num_services"] = 12345678
    return ctxt

続いて、アドレス帳の分類を追加したいと思います。views.pyでリストを作成して、htmlでfor文を使って要素を追加していく方法を使います。

テンプレート(htmlファイル)のリスト作成の例

リスト作成方法

リスト作成方法の概要
htmlファイルにおいて下記のように記述する。

<リストの中身を順番に繰り返して表示したい>
for/empty文

{% for アイテム in リスト %}
アイテムを表示する
{% empty %}
リストが空の場合表示される
{% endfor %}

現在時刻を表示する = {% now %}の活用

手順②:address.htmlの変更を加える箇所を{{ 変数名 }}タグで置換する。
(apps/templates/address.html)
{% extends "base.html" %}
{% load static %}
{% load humanize %}

{% block main %}
<h1>アドレス帳</h1>
<h2>登録件数</h2>
<p>{% now "Y年m月d日 H時i分" %}現在までに{{{ num_registration|intcomma }}件のアドレスが登録されていました。</p>
<h2>分類</h2>
<ul>
{% for classification in classifications %}
<li>{{ classification }}</li>
{% empty %}
<li>分類がありません。</li>
</ul>
{% endblock %}
• humanizeはsetting.py => INSTALLED_APPSに追加する必要がある。
 'django.contrib.humanize'
手順③:views.pyで変更内容を定義する。
(apps/views.py)
from django.views.generic import TemplateView

class AboutView(TemplateView):
    template_name = "address.html"

def get_context_data(self):
    ctxt["num_services"] = 12345678
    ctxt["classifications"] = [
    "家族",
    "仕事",
    "趣味",
    "町内会",
    "役所",
    "携帯ショップ"
    ]
    return ctxt

例5:アクセスユーザーの種類によってユーザー名を表示し分ける

次に、ユーザーに応じて表示内容を変更する方法を解説致します。まずは、Djangoにおける条件分岐の構文を紹介します。

Djangoにおける条件分岐
htmlファイルにおいて下記のようなコードを入力する。
<条件によって表示する内容を変えたい>
if/elif/else

{% if 条件1 %}
条件1が満たされたときにここが表示される。
{% elif 条件2 %}
条件2が満たされたときにここが表示される。
{% else %}
どの条件も満たされなかったときにここが表示される。
{% endif %}

それでは、実際にhtmlファイルとviews.pyを作成していきます。

手順①-②:index.htmlに都度変更を加える箇所を{{ 変数名 }}タグで置換する。
(apps/templates/index.html)
{% extends "base.html" %}
{% load static %}
{% load humanize %}

{% block main %}
{% if username == "自分の名前" %}
<h1>自分です。</h1>
{% elif username %}
<h1>{{ username }}さん、ようこそ!</h1>
{% else %}
<h1>匿名さん、ようこそ!</h1>

{% endblock %}
手順②:address.htmlの変更を加える箇所を{{ 変数名 }}タグで置換する。
(apps/templates/address.html)
{% extends "base.html" %}
{% load static %}
{% load humanize %}

{% block main %}
<h1>アドレス帳</h1>
<h2>登録件数</h2>
<p>これまでに{{ num_registration|intcomma }}件のアドレスが登録されていました。</p>
<h2>分類</h2>
<ul>
<li>家族</li>
<li>仕事</li>
<li>趣味</li>
</ul>
{% endblock %}
• humanizeはsetting.py => INSTALLED_APPSに追加する必要がある。
 'django.contrib.humanize'
手順③:views.pyで変更内容を定義する。
(apps/views.py)
from django.views.generic import TemplateView

class IndexView(TemplateView):
template_name = "index.html"

def get_context_data(self):
ctxt = super().get_context_data()
ctxt["username"] = "太郎"
return ctxt

class AboutView(TemplateView):
template_name = "about.html"

• ctxt:開発者の間では一般的な記法。辞書型。
• super():TemplateViewが用意しているUserを規定する変数
• super().get_context_data():TemplateViewが用意しているUserを表す変数からデータを取得している。

TIME_ZONEの編集

settings.pyのデフォルトでは、TIME_ZONE = ‘UTC’となっています。TIME_ZONE = ‘ASIA/TOKYO’に変更すると日本時間で表示されるようになります。

footerの年を変更

<div>
<p>Copyright 2015-{% now "Y"%}</p>
</div>

コメント

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