Django入門: オブジェクトを描画 ~ 簡単な一行掲示板アプリを作る その10【Windows10】
- 作成日: 2020-10-22
- 更新日: 2023-12-26
- カテゴリ: Django
はじめに
この記事は「Djangoで一行掲示板を作ろう」という趣旨のシリーズの記事です。
前回までにDjangoのプロジェクトとアプリを作成し、ルート情報とビューを接続し、テンプレートを描画して、モデルを作りマイグレーションを行い、ビューでオブジェクトを取得しました。
今回から作成したPost
モデルを使ってテンプレート内で描画していきたいと思います。
また前提としてOSはWindows10, シェルはコマンドプロンプトを使います。
Pythonの仮想環境を使っていますのでvenv\Scripts\activate
を実行してある前提です。
仮想環境についてはこちらの第一回の記事をご覧ください。
それから初期位置の作業フォルダはプロジェクト内のmanage.py
があるフォルダです。
テンプレートファイルの構成
前回までのテンプレートファイルはbbs\templates\bbs\home.html
のように1つだけのテンプレートで構成していました。
今回の例ではテンプレートファイルは1つだけの構成でも可能なんですが、より柔軟性のある構成をご紹介したいので、テンプレートファイルを1つ増やしたいと思います。
テンプレートファイルは別のテンプレートファイルを継承することが可能です。
つまりベースとなるテンプレートファイルを1つ作り、そのベースを継承してhome.html
を作ってみたいと思います。
こうすることで、共通したHTMLをベースとなるテンプレートファイルに記述することが可能になり、home.html
の負担を減らせます。
また、一部のHTMLを共通化することで色々なテンプレートファイルで統一が取れるようになります。
今回は↓のようなテンプレートファイルの構成にしたいと思います。
- bbs\templates\bbs\base.html
- bbs\templates\bbs\home.html
base.htmlの編集
エディタでbbs\templates\bbs\base.html
を開き↓のように記述します。
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
内容的にはただのHTMLに近いものですが、テンプレートファイル特有の記述を使っている所を解説します。
<title>{{ title }}</title>
↑の部分はコンテキスト内のtitle
変数をHTMLのtitle
タグ内に出力しています。
こうすることでビューからWebページのタイトルを指定できるようになります。
変数の出力は↑のように変数を{{ }}
で囲います。
{% block content %}
{% endblock %}
↑はテンプレートファイル内でcontent
という名前のブロックを作っています。
「ブロック」というのはテンプレートファイル内の「区画」のことです。
継承元、つまりこのbase.html
などに↑のようにブロックを作ると、このbase.html
を継承したテンプレートファイルは、このブロックに別のHTMLを注入できるようになります。
つまり↑は「ここにcontentというブロックを作っておくから、継承した人は適当に使ってね」という感じの記述です。
このcontent
ブロックはbody
タグ内にあるので、このcontent
ブロックに注入されたHTMLは↑のbody
タグ内に展開されることになります。
home.htmlの編集
次にbbs\templates\bbs\home.html
をエディタで開き↓のように編集します。
{% extends 'bbs/base.html' %}
{% block content %}
<h1>{{ title }}</h1>
{% endblock %}
🦝 < モデルは?
はい。モデルは少々お待ちください。
その前に↑のコードを解説します。
{% extends 'bbs/base.html' %}
上の部分はextends
という命令文を実行しています。
テンプレートファイルのextends
文は第1引数に継承元のテンプレートファイルのパスを指定します。
↑の場合はbbs/base.html
になっていますが、これはbbs/templates/bbs/base.html
のことです。
bbs/templates
が省略されていることに注意してください。
この命令文を実行することで、home.html
はbase.html
を継承したことになります。
継承しているので、base.html
内のcontent
ブロックにHTMLを注入できるようになります。
また、コンテキスト内の変数はbase.html
とhome.html
で共有されるようになります。
{% block content %}
<h1>{{ title }}</h1>
{% endblock %}
↑のコードで継承元のbase.html
内のcontent
ブロックに<h1>{{ title }}</h1>
というHTMLを注入しています。
<h1>{{ title }}</h1>
はh1
タグ内にtitle
変数を出力しているところです。
開発用サーバーで動作確認
ここまでの変更を開発用サーバーで確認してみましょう。
> python manage.py runserver 0.0.0.0:8123
特に問題がなければ↓のように表示されると思います。
モデルを出力する
さきほどのhome.html
を↓のように改造します。
{% extends 'bbs/base.html' %}
{% block content %}
<h1>{{ title }}</h1>
<ul>
{% for post in posts %}
<li>{{ post.id }}: {{ post.content }}</li>
{% endfor %}
</ul>
{% endblock %}
↓の部分が新しく加わりました。
<ul>
{% for post in posts %}
<li>{{ post.id }}: {{ post.content }}</li>
{% endfor %}
</ul>
Djangoのテンプレートではfor
文でループ処理を書くことが出来ます。
{% for post in posts %}
...
{% endfor %}
↑の部分ではposts
というコンテキスト内の変数(これはQuerySet
ですね)をfor
文で回して、post
という変数に展開しています。
<li>{{ post.id }}: {{ post.content }}</li>
↑の部分ではpost
の属性id
とcontent
をli
タグ内に出力しています。
先述したようにmodels.Model
を継承したモデルは自動でid
というフィールドを定義します。
content
は今シリーズで私たちが作ったフィールドです。
posts
はビュー内のPost.objects.all()
で取得したQuerySet
です。
QuerySet
はこのようにテンプレートファイル内のfor
文で回すことが出来ます。
そしてQuerySet
をfor
文で回すとPost
のオブジェクトとして展開することが出来ます。
では↑の変更を加えた上で再度runserver
で動作確認をしてみましょう。
すると先ほどと変わらない画面が出力されているはずです。
これはそのはずで、Post
というモデルを作成しマイグレーションも行いましたが、肝心のデータはまだDBに保存していないので、posts
の中身も空なわけです。
おわりに
今回はテンプレートファイル内でPost
のオブジェクトを描画する所までやりました。
次回以降から管理サイトを使ってPost
のデータを追加してみたいと思います。
🦝 < お楽しみに