Pythonで学ぶ 家計簿アプリ開発(第2回)~ Jinja2テンプレートで支出一覧を表示する ~

GitHubでつくって学ぶ

はじめに

前回(第1回)は、Flaskの最小構成でブラウザに「Hello, PC-LABO!」と表示するところまでを確認した。今回は、そこにテンプレートの仕組みを導入し、支出データを一覧として表示できるようにする。

まだデータの保存機能は無いので、今回はPythonのコード内に直接書いた固定データを表示するだけである。データベースを使った保存は、第4回で扱う予定である。

今回やること

  • Flaskにおける「テンプレート」の考え方を知る
  • templatesフォルダにHTMLファイルを用意し、Pythonから表示する
  • 固定の支出データを、一覧表として画面に表示する
  • 簡単なCSSで見た目を整える

テンプレートとは

前回は、Pythonの関数の中に直接文字列を書いて、それをそのままブラウザに返していた。しかしこの方法では、HTMLが複雑になるほどPythonのコードが読みにくくなってしまう。

そこでFlaskでは、HTMLを別ファイルに分けて用意し、Python側からそのHTMLに値を渡して表示する、という仕組みが使われる。この別ファイルのことをテンプレートと呼び、Flaskは内部でJinja2というテンプレートエンジンを使っている。

Jinja2を使うと、HTMLの中に{{ }}{% %}という特別な記法を書くことで、Python側の変数やループをHTMLに埋め込める。

フォルダ構成

Flaskには「このフォルダに置けば、自動的にテンプレートとして扱われる」という決まりがある。

02_templates/
├── app.py
├── templates/
│   └── index.html
└── static/
    └── style.css
  • templatesフォルダ
    HTMLファイルを置く場所。render_template()で読み込む対象になる
  • staticフォルダ
    CSSや画像など、そのまま配信したいファイルを置く場所

Flaskのデフォルト設定では、テンプレートはtemplates、静的ファイルはstaticというフォルダ名で置くことになっている。今回はこのデフォルト設定をそのまま使用する。

コード解説

app.py

from flask import Flask, render_template

app = Flask(__name__)

expenses = [
    {"date": "2026-08-01", "category": "食費", "item": "スーパー", "amount": 3200},
    {"date": "2026-08-03", "category": "交通費", "item": "電車", "amount": 480},
    {"date": "2026-08-05", "category": "娯楽費", "item": "映画", "amount": 1800},
]


@app.route("/")
def index():
    return render_template("index.html", expenses=expenses)

expensesという、辞書を要素に持つリストを用意した。1件の支出を1つの辞書(日付・カテゴリ・内容・金額)で表している。

render_template("index.html", expenses=expenses)の部分がポイントである。templates/index.htmlを読み込み、expensesという名前でテンプレート側にデータを渡している。

templates/index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>家計簿アプリ</title>
  <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
  <h1>家計簿アプリ</h1>
  <table>
    <thead>
      <tr>
        <th>日付</th>
        <th>カテゴリ</th>
        <th>内容</th>
        <th>金額</th>
      </tr>
    </thead>
    <tbody>
      {% for expense in expenses %}
      <tr>
        <td>{{ expense.date }}</td>
        <td>{{ expense.category }}</td>
        <td>{{ expense.item }}</td>
        <td>{{ expense.amount }}円</td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</body>
</html>
  • {% for expense in expenses %} 〜 {% endfor %}:Python側から渡されたexpensesを1件ずつ取り出し、<tr>を繰り返し出力している
  • {{ expense.date }}:辞書の値を、そのまま画面に埋め込んでいる
  • {{ url_for('static', filename='style.css') }}staticフォルダの中のstyle.cssを指すURLを、自動的に組み立ててくれる

static/style.css

body {
  font-family: sans-serif;
  margin: 2rem;
}

table {
  border-collapse: collapse;
}

th, td {
  border: 1px solid #ccc;
  padding: 0.5rem 1rem;
  text-align: left;
}

th {
  background-color: #f0f0f0;
}

表に罫線を付け、見出し行(th)に背景色を付けているだけの、簡単なCSSである。staticフォルダに置いたこのファイルが、index.html<link>タグから読み込まれている。

動作確認

flask --app app run --debugで起動し、ブラウザで開くと、支出データが表として一覧表示されているはずである。app.pyexpensesにデータを1件追加して保存すると、--debugオプションのおかげで自動的に再読み込みされ、表にも反映される。この挙動も合わせて確認しておくとよい。

--debugは開発中の確認に使用するためのものです。本番環境では使用しないようにしよう。

今回のまとめ

  • Flaskでは、HTMLをtemplatesフォルダに分けて管理し、Jinja2という仕組みで値を埋め込む
  • render_template()で、Python側のデータをテンプレートに渡せる
  • staticフォルダに置いたファイルは、url_for('static', ...)で参照できる

次回予告

次回は、今回表示するだけだった支出データを、HTMLフォームから追加・削除できるようにする。ユーザーの入力をPython側で受け取る方法を扱う予定である。

ソースコード

GitHub:pc-labo-python-learning/02_templates

コメント

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