※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part9)〜URLconfの作成~
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part11)〜uuidを使う~

【初心者チュートリアル】Django2でブログ作成(Part10)〜templateの作成~

web開発 python3 Django python Djangoチュートリアル

投稿日:2019年11月14日

このエントリーをはてなブックマークに追加
Djangoは簡単にWebアプリケーションを作成できるフレームワークです。この記事は初心者の方向けのDjangoチュートリアルです。

はじめに

この記事ではDjangoTemplate言語でtenplateを作成します。これが終わればいよいよ見た目の確認が始められます(長かった...)!


template

※この記事ではblogアプリケーションのArticleテーブルにレコードがいくつか存在する前提で進んでいきます。レコードが存在しない場合は管理サイトで適当なレコードをいくつか作成して、それを公開状態にしてから進めましょう。

templateファイル作成の準備

まずは必要なディレクトリとファイルを作成します。

sample_blog/blog/templates/
└── blog
│   ├── article_detail.html
│   └── article_list.html
└── base.html

テンプレートを書き始める前に、まずはちゃんと描画できるか確認してみましょう。

html
これはdetail.htmlです。
html
これはlist.htmlです。

開発用サーバーを起動して、ブラウザで動作を確認してみましょう。

ターミナル
/sample_blog $ python manage.py runserver

まずarticle_list()関数の方を確認してみましょう。http://localhost:8000/blog/をブラウザで確認してみましょう。

ちゃんと描画できていますね。次にarticle_detail()関数の方を確認してみましょう。こちらはurlで存在するArticleレコードのidを受け取る必要がありました。

とりあえず適当なidを渡してみます。

http://localhost:8000/blog/1/

そのレコードは存在しないとエラーがかえってきました。これまでのチュートリアルでデータの削除なんかもしたので、id=1のレコードはそこで削除されていたのでしょう。

他のidのレコードを試してみます。

http://localhost:8000/blog/2/

OK!ちゃんと表示できました!

Ctrl+Cでサーバーを停止しましょう。
もし、表示するべきArticleレコードのidがわからない場合は下の方法で確認してみましょう。

ターミナル
$ python manage.py shell
Python 3.6.8 (default, Oct  7 2019, 12:59:55) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import Article
>>> Article.objects.all()[0].id

各templateファイルについて

先程blogのtemplatesディレクトリの中にbase.html、更にその中のarticleレコードの中にlist.htmlとdetail.htmlを作成しました。Djangoのテンプレート言語ではプログラミング言語の様に他のテンプレートをincludeすることができます。これによって重複する処理をまとめることができます。

  • base.html:base.htmlにはhtmlタグ、bodyタグの様に全てのページで共通のHTMLを記述します。他のtemplateからincludeされて利用されます。
  • list.html:viewから渡されたcontextから記事のタイトルと記事詳細へのリンクをリスト表示するHTMLを記述します。
  • detail.html:viewから渡されたcontextから記事の詳細を表示するHTMLを記述します。

Django Template Language

これから作成するtemplateはDjango独自のテンプレート言語を使って記述します。
初めての方は『HTMLの中でpythonを記述するための言語』と考えておくと良いでしょう。ここでその全ての使い方を解説することはできないので、今回使う機能だけ説明します。

  • {{ variable }}:変数を描画するためのタグです。レンダリングされるときにvariableの中の値に置き換わります。
  • {% tag %}:templateをプログラミングの様に操作します。tagによって処理が異なります。
  • {{ variable|filter }}:variableの値をfilterして描画します。ここで言うfilterとはDjangoのobjectの時の検索で使ったものとは全然別物で、『状態を変化』させるという意味で使われています。

DjangoTemplateLanguageについて詳しく知りたい場合は公式ドキュメントを参照してください。

templateを作成しよう

実際にtemplateを記述しましょう。(今HTMLがわからない方も今はとりあえずわからないままでいいので書いてみましょう!)

sample_blog/blog/templates/base.html
<!DOCTYPE html>
<html>
    <head>
        <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
        <header>
            Sampleブログ
        </header>
        <main>
            <div class="content">
                {% block content %}
                {% endblock %}
            </div>
        </main>
    </body>
</html>

簡単にDjangoのTemplate Tagだけ解説します。ここで使われているTemplate Tagは2つ。{% block title %}{% endblock %}{% block content %}{% endblock %}です。これはblockの定義しています。{% block ブロック名 %}{% endblock %}の様に定義しておくと他のテンプレートからこのhtmlファイルを継承して、そちら側からこのblockにコンテンツを埋めることができるのです。今回ここではtitlecontentという名前でblockを定義しています。

呼び出す側の使い方は次のlist.htmlで説明します。

sample_blog/blog/templates/blog/article_list.html
{% extends "base.html" %}
{% block title %}ブログ一覧|Sampleブログ{% endblock %}
{% block content %}
  <h1>ブログ一覧</h1>
  {% for article in articles %}
    <h2>
      <a href="{% url 'blog:article_detail' id=article.id %}">
        {{ article.title }}
      </a>
    </h2>
    <p class="date">
      公開日:{{ article.publish }}
    </p>
    <p>by {{ article.author }}</p>
    {{ article.body|truncatechars:30 }}
  {% endfor %}
{% endblock %}

この様に他のDjangoTemplateを継承する場合は先頭に{% extends "ファイルのパス" %}と記述し、埋めるコンテンツは{% block ブロック名 %}{% endblock %}の間に記述します。

{% extends "テンプレートのパス"%}

{% block ブロック名 %}
テンプレートのブロックに入れたいHTML
{% endblock %}

{% block ブロック名 %}
テンプレートのブロックに入れたいHTML
{% endblock %}
︙

また、新たにタグとしてfor文を使っています。article_list()からこのtemplateにはarticlesというArticleオブジェクトの配列が渡されています。Django Templateは

{% for variable in 配列 %}
繰り返し書き出すhtml
{% endfor %}

で配列をループでレンダリングできます。

次にそのループの中の"{% url 'blog:article_detail' id=article.id %}"に注目してください。これは記事詳細のページのリンクを書き出すためのタグです。前回のURLconfの中でROOTURLconfの中のinclude()namespace=blogarticle_detail()にマッピングするpath()name=article_detailという値を渡していました。
URLconfをこのように定義しておくとDjangoTemplate内でこの名前でURLを呼び出すことができます。呼び出す場合は

{% url "namespace:name" オプションの引数の値 %}

とします。

{{ article.title }}{{ article.publish }}{{ article.author }}はループ処理しているArticleオブジェクトの変数値を書き出しています。

{{ article.body|truncatewords:30 }}に注目してみてください。このように変数値の呼び出しはパーティカルバー(|)でレンダリングにオプションを加えることができます。今回のtruncatewordsはその名の通り、呼び出しを指定した文字数までで区切ることができます。(ちなみにこれは僕のブログ記事一覧でも使っている機能です。)

ここで一端開発用サーバーを起動して確認してみましょう。

ターミナル
$ python manage.py runserver

http://localhost:8000/blogを開いてみましょう。

記事の一覧表示ができている!!

まだ記事の名前をクリックしても記事詳細のテンプレートdetail.htmlには何も書いていないので記事の情報は見えないですね。

では次にdetail.htmlを作成しましょう。

sample_blog/blog/templates/blog/article_list.html
{% extends "base.html" %}

{% block title %}{{ article.title }}{% endblock %}

{% block content %}
  <h1>{{ article.title }}</h1>
  <p class="date">
    公開日:{{ article.publish }}
  </p>
  <p>
  by {{ article.author }}
  </p>
  {{ article.body }}
{% endblock %}

基本的に使用しているタグはlist.htmlと変わらないので説明は不要ですね?

もう一度http://localhost:8000/blogを開いてみましょう。今度は記事のリンクを押すと記事の詳細を表示してくれるのではないでしょうか?

Djangoはどうやってtemplateファイルを見つけた?

view関数でtemplateのファイルを指定する時、"blog/article/list.html""blog/article/detail.html"の様に指定しました。しかし、これらのファイルを実際のパスはsample_blog/blog/templates/blog/article/list.htmlやsample_blog/blog/templates/blog/article/detail.htmlです。

どういうことでしょうか?

Djangoのtemplateファイルの扱いの設定はsettingファイルのTEMPLATESで定義します。
すこしだけみてみましょう。

sample_blog/sample_blog/settings.py
[...]

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',
            ],
        },
    },
]

[...]

ここでDIRSAPP_DIRSの設定がDjangoがtemplateファイルを探しに行くときの設定になります。

  • DIRS : DIRS には、エンジンがテンプレートのソースファイルを検索するディレクトリのリストを、検索順に定義します。デフォルトでは何もないので、特にここを起点に検索はされません。
  • APP_DIRS : APP_DIRS には、エンジンがインストールしたアプリケーション内のテンプレートを検索するべきかどうかを指定します。

デフォルトの状態ではAPP_DIRSTrueになっていて、ここを起点にtemplateファイルは検索されます。その場合、DjangoはINSTALLED_APPSに指定されたすべてのアプリケーションディレクトリ内のtempaltes/のディレクトリを探しにいきます。

つまりテンプレートのパスとして"blog/article_detail.html"を指定した場合、全てのアプリケーションディレクトリのtemplates/blog/article_detail.htmlを探しに行くことになります。


さいごに

とりあえずこの章でシンプルな(ものすごくシンプルな)ブログアプリケーションができあがりました。

まとめ

  • templateファイルはデフォルトではアプリケーションのtemplatesディレクトリをルートに作成する。
  • templateファイルの設定は設定ファイルのTEMPLATESに記述する。
  • templateファイルはDjangoテンプレート言語で記述する。

Advance

以下はDjangoのtemplateに関する追加Tipsです。興味があれば覗いてみてください。

このエントリーをはてなブックマークに追加

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part9)〜URLconfの作成~
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part11)〜uuidを使う~

関連記事

記事へのコメント
1:名無しさん
2021年12月7日16:53

「では次にdetail.htmlを作成しましょう。」の次にあるソースコード欄の名前が article_list.html になっています。たぶん、article_detail.htmlのことだと思います。