こんにちは、Tech Samuraiです!
前回の記事「【Webアプリ応用編 #1】Python標準ライブラリだけでOK!SQLiteデータベース入門」では、PythonとSQLiteを使って、プログラムのデータをファイルに保存・読み込みする方法を学びましたね。
データベースという強力な「記憶装置」の使い方はマスターしました。今回の冒険の目的は、この記憶装置を、私たちが作った**FlaskのWebアプリケーションと接続する**ことです。
具体的には、ユーザーがWebページのフォームに入力した名前とメッセージを受け取り、それをSQLiteデータベースに永続的に保存する**「一言掲示板」**のバックエンドを構築します。この記事を終える頃には、あなたのWebアプリは、ユーザーとの対話を「記憶」し、積み重ねていくことができるようになります!
ステップ1:データベースの準備
まずは、前回の知識を元に、掲示板の投稿を保存するためのデータベースファイルとテーブルを準備します。`init_db.py`という名前で、以下のスクリプトをプロジェクトフォルダに作成し、一度だけ実行してください。
# init_db.py
import sqlite3
conn = sqlite3.connect('guestbook.db')
cursor = conn.cursor()
# postsテーブルが既に存在する場合は削除してから再作成する
# (開発中はリセットが簡単なこの方法が便利)
cursor.execute("DROP TABLE IF EXISTS posts")
cursor.execute("""
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
message TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
""")
conn.commit()
conn.close()
print("データベースを初期化しました。guestbook.db が作成されました。")
ターミナルでpython3 init_db.py
を実行し、`guestbook.db`ファイルが作成されれば準備完了です。
ステップ2:入力フォームの作成 (`templates/index.html`)
次に、ユーザーが名前とメッセージを入力するためのHTMLフォームを用意します。前回のWebアプリ入門で作った`templates/index.html`を、以下のように書き換えましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>一言掲示板</title>
<style>
/* ページ全体のスタイル */
body {
font-family: "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
}
/* コンテンツを中央に配置するラッパー */
.container {
max-width: 700px;
margin: 0 auto;
background-color: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
/* 見出しのスタイル */
h1, h2 {
color: #333;
border-bottom: 2px solid #007BFF;
padding-bottom: 10px;
}
/* フォーム全体のスタイル */
form {
background-color: #f8f9fa;
padding: 20px;
border-radius: 5px;
border: 1px solid #ddd;
margin-bottom: 30px;
}
/* テキスト入力欄とテキストエリアのスタイル */
input[type="text"], textarea {
width: 95%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
margin-top: 5px;
}
/* 送信ボタンのスタイル */
input[type="submit"] {
background-color: #007BFF;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
/* 送信ボタンにマウスを乗せた時のスタイル */
input[type="submit"]:hover {
background-color: #0056b3;
}
/* 投稿一件ずつのスタイル */
.post {
border: 1px solid #eee;
padding: 15px;
margin-bottom: 15px;
border-radius: 5px;
background-color: #fff;
}
/* 投稿情報のスタイル(名前や日時) */
.post-info {
color: #777;
font-size: 0.9em;
}
.post-message {
margin-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<h1>一言掲示板へようこそ!</h1>
<form method="post" action="">
<p>
<label for="name">名前:</label><br>
<input type="text" name="name" id="name" required>
</p>
<p>
<label for="message">メッセージ:</label><br>
<textarea name="message" id="message" rows="5" required></textarea>
</p>
<p>
<input type="submit" value="投稿する">
</p>
</form>
<hr>
<h2>投稿一覧</h2>
<div class="post">
<p class="post-info"><strong>田中</strong> <span>投稿日時: 2025-09-06 14:30:15</span></p>
<p class="post-message">こんにちは!初めての投稿です。</p>
</div>
<div class="post">
<p class="post-info"><strong>鈴木</strong> <span>投稿日時: 2025-09-06 12:10:48</span></p>
<p class="post-message">いい天気ですね。<br>掲示板のデザイン、見やすいです。</p>
</div>
<div class="post">
<p class="post-info"><strong>佐藤</strong> <span>投稿日時: 2025-09-05 21:55:01</span></p>
<p class="post-message">テスト投稿です。</p>
</div>
</div>
</body>
</html>
method="post"
で、入力されたデータをサーバーに送信するように設定しています。
ステップ3:Flaskとデータベースの連携 (`app.py`)
いよいよ核心部分です。Flaskアプリケーション (`app.py`) を修正し、フォームから`POST`リクエストが来たときに、そのデータをSQLiteデータベースに保存するロジックを追加します。
import sqlite3
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
DATABASE = 'guestbook.db'
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# --- フォームが送信されたときの処理 ---
# 1. フォームからデータを取得
name = request.form['name']
message = request.form['message']
# 2. 簡単なバリデーション
if name and message:
# 3. データベースに接続
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
# 4. データをINSERT
sql = "INSERT INTO posts (name, message) VALUES (?, ?)"
cursor.execute(sql, (name, message))
conn.commit()
conn.close()
# 5. 投稿後は、トップページにリダイレクトする
return redirect(url_for('index'))
# --- 初めてページにアクセスしたときの処理 (GET) ---
# (今回はまだ投稿を表示しないので、シンプルにテンプレートを返すだけ)
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
コードのポイント解説
if request.method == 'POST':
Webページが初めて表示されるとき(`GET`)と、フォームの「投稿する」ボタンが押されたとき(`POST`)で処理を分けています。request.form['name']
`POST`リクエストで送られてきたフォームデータにアクセスする方法です。HTMLの`name`属性と対応しています。redirect(url_for('index'))
これはWebアプリ開発の重要なお作法です。フォームを送信した後、ユーザーをトップページに**リダイレクト(再案内)**しています。これにより、ユーザーがブラウザの更新ボタンを押しても、同じデータが二重に投稿されてしまうのを防ぎます。
動作確認
- ターミナルで
python3 app.py
を実行して、Flaskサーバーを起動します。 - ブラウザで
http://127.0.0.1:5000
にアクセスし、フォームに名前とメッセージを入力して「投稿する」ボタンを押します。 - ページがリロードされ、入力欄が空になれば成功です!(まだ投稿内容は表示されません)
- 本当に保存されたか確認するには、前回の記事で使った読み込み用のスクリプトを別のターミナルで実行するか、
sqlite3 guestbook.db
コマンドでデータベースの中身を覗いてみましょう。
まとめと次回予告
今回は、Webアプリ応用編の第2回として、Webフォームとデータベースを接続し、ユーザーの入力を永続的に保存する仕組みを構築しました。
- Webフォームからの**POSTリクエスト**をFlaskで処理する方法。
- 受け取ったデータを**SQLiteデータベースに`INSERT`**する流れ。
- 二重投稿を防ぐための**Post/Redirect/Get (PRG)** パターン。
私たちのアプリは、ついにユーザーとの対話を「記憶」し、積み重ねていく能力を手に入れました。あとは、その記憶をユーザーに見せてあげるだけです。
次回、いよいよシリーズ完結編では、データベースに保存された全ての投稿を**`SELECT`**文で読み出し、掲示板の投稿一覧として**Webページに動的に表示**します。本当の意味で「生きている」Webアプリケーションを完成させましょう!お楽しみに!
コメント