4日目のゴール
4日目のテーマは
「Flaskのルーティングを“入力付きのページ”まで広げる」 ことです。
1〜3日目までは、
ブラウザからURLにアクセスして「サーバー側が用意した内容」を返すだけでした。
4日目では一歩進んで、
フォームから値を送るイメージを持つ
GET と POST の違いを理解する
同じURLで「表示」と「送信後の処理」を書き分ける
ここまでを、自分の言葉で説明できるレベルを目指します。
まだテンプレートファイル(templates/*.html)は使わず、
あえて「1ファイル+シンプルなHTML文字列」で進めます。
構造に集中したいからです。
GET と POST のざっくりイメージ
ブラウザがサーバーに「どうやって話しかけるか」
Webの世界では、
ブラウザがサーバーに話しかけるときに「メソッド」という種類を使い分けます。
いちばんよく出てくるのが、
GET と POST です。
GET は
「ページをください」「情報をください」
というときに使われます。
URLを直接叩いたり、リンクをクリックしたりしたときは、基本的に GET です。
POST は
「このデータを送ります」「フォームの内容をサーバーに渡します」
というときに使われます。
ログインフォーム、問い合わせフォーム、投稿フォームなどは、たいてい POST です。
Flaskでは、
どのメソッドを受け付けるかをルートごとに指定できます。
Flaskでメソッドを指定する基本形
methods=["GET", "POST"] の意味
まずは、最小の例を見てみましょう。
from flask import Flask, request
app = Flask(__name__)
@app.route("/echo", methods=["GET", "POST"])
def echo():
return f"メソッド: {request.method}"
if __name__ == "__main__":
app.run(debug=True)
Pythonこのコードのポイントをかみ砕きます。
methods=["GET", "POST"] と書くことで、「このURLは GET と POST の両方を受け付ける」と宣言していること。
何も指定しない場合、Flaskはデフォルトで GET だけを受け付けます。
request.method には、実際に使われたメソッド名(”GET” や “POST”)が入っていること。
これを表示することで、「今どっちで来たか」を確認できます。
ブラウザで /echo にアクセスすると、
普通は GET なので「メソッド: GET」と表示されます。
POST を試すには、フォームやツールが必要ですが、
4日目では「GET と POST をルーティングで区別できる」という感覚を持てれば十分です。
フォームを使った「名前入力ページ」を作る
同じURLで「表示」と「送信後」を切り替える
ここからが今日の本番です。
次のような流れのページを作ります。
最初にアクセスしたときは、名前を入力するフォームを表示する
フォームに名前を入力して送信すると、「こんにちは、〇〇さん」と表示する
これを、同じ /hello というURLで実現します。
from flask import Flask, request
app = Flask(__name__)
@app.route("/hello", methods=["GET", "POST"])
def hello():
if request.method == "GET":
return """
<h1>名前を教えてください</h1>
<form method="post">
<input type="text" name="name" placeholder="お名前">
<button type="submit">送信</button>
</form>
"""
name = request.form.get("name", "").strip()
if not name:
return """
<h1>名前が空です</h1>
<p>戻って、名前を入力してください。</p>
<a href="/hello">戻る</a>
"""
return f"""
<h1>こんにちは、{name} さん!</h1>
<p>Flask のフォーム送信ができました。</p>
<a href="/hello">もう一度入力する</a>
"""
if __name__ == "__main__":
app.run(debug=True)
Pythonここで、重要なところをじっくり分解します。
GET と POST で処理を分ける if 文
「最初の表示」と「送信後の処理」を頭の中で分ける
@app.route("/hello", methods=["GET", "POST"]) と書いたことで、
この関数は GET と POST の両方を受け付けます。
中身では、こう分けています。
if request.method == "GET":
# フォームを表示する
else:
# フォーム送信後の処理(POST)
Pythonここでの本質は、
GET のときは「ページを見に来ただけ」
POST のときは「フォームからデータが送られてきた」
という役割分担を、
1つの関数の中で if 文を使って切り替えていることです。
このパターンは、
現場のFlaskアプリでもめちゃくちゃよく出てきます。
request.form でフォームの値を受け取る
request.args との違いを整理する
3日目で、クエリパラメータ(?name=xxx)を request.args から受け取りました。
フォーム送信(POST)のときは、request.form から値を受け取ります。
name = request.form.get("name", "").strip()
Pythonここでやっていることを分解します。
request.form は「フォームから送られてきたデータ」を表すオブジェクトrequest.args が「?以降」だったのに対して、request.form は「POSTされたフォームの中身」です。
.get("name", "") で、name という名前の入力欄の値を取り出している
HTML側で name="name" と書いた入力欄に対応します。
第二引数の "" は、値がなかったときのデフォルトです。
.strip() で前後の空白を削っている
スペースだけの入力を「空」とみなしたいので、
前後の空白文字を取り除いています。
この一行で、
「フォームから送られてきた名前を、きれいな文字列として受け取る」
という処理が完結しています。
HTMLフォームの最低限の構造を理解する
form タグと input の役割
フォーム部分のHTMLをもう一度見てみましょう。
<form method="post">
<input type="text" name="name" placeholder="お名前">
<button type="submit">送信</button>
</form>
ここで押さえておきたいのは、次の3点です。
<form method="post">
このフォームは「POSTメソッドで送信する」という宣言です。action を省略すると、「今のURL」に送信されます。
つまり /hello に POST されます。
<input type="text" name="name">
ここで name="name" と書いた値が、サーバー側の request.form.get("name") と対応します。
「フォームの入力欄の名前」と「サーバー側で取り出すキー」が一致している必要があります。
<button type="submit">
このボタンを押すと、フォームの内容がサーバーに送信されます。
ブラウザが自動的に POST リクエストを作ってくれます。
4日目では、
HTMLを完璧に理解する必要はありません。
「フォームは <form> の中に <input> と <button> があるんだな」
くらいのイメージで十分です。
例題:簡単な「足し算フォーム」を作る
2つの数値を入力して、サーバー側で計算する
次は、もう少し「アプリっぽい」例をやってみましょう。
2つの数字を入力するフォームを作り、
送信すると「合計」を表示するページです。
from flask import Flask, request
app = Flask(__name__)
@app.route("/add", methods=["GET", "POST"])
def add():
if request.method == "GET":
return """
<h1>足し算フォーム</h1>
<form method="post">
<input type="number" name="a" placeholder="数字A">
<input type="number" name="b" placeholder="数字B">
<button type="submit">計算する</button>
</form>
"""
a_str = request.form.get("a", "").strip()
b_str = request.form.get("b", "").strip()
if not a_str or not b_str:
return """
<h1>入力エラー</h1>
<p>AとBの両方に数字を入力してください。</p>
<a href="/add">戻る</a>
"""
try:
a = float(a_str)
b = float(b_str)
except ValueError:
return """
<h1>入力エラー</h1>
<p>数字として解釈できませんでした。半角の数字を入力してください。</p>
<a href="/add">戻る</a>
"""
result = a + b
return f"""
<h1>計算結果</h1>
<p>{a} + {b} = {result}</p>
<a href="/add">もう一度計算する</a>
"""
if __name__ == "__main__":
app.run(debug=True)
Pythonここでの重要ポイントを深掘りします。
GET のときは「フォームを見せるだけ」
POST のときは「フォームの値を受け取り、検証して、計算する」
という役割分担が、はっきり分かれています。
request.form.get("a") と request.form.get("b") で、2つの入力欄の値を受け取っている
HTML側の name="a" と name="b" に対応しています。
空チェックと数値変換をサーバー側でやっている
ユーザーが何を入力するかはコントロールできないので、
サーバー側で必ず「空でないか」「数値に変換できるか」を確認しています。
ここで大事なのは、
「サーバー側でちゃんと入力チェックをする」という感覚です。
フロント側(ブラウザ)だけに頼らない、というのが現場の基本です。
ルーティングの視点から見た「フォーム付きページ」
URLは1つ、役割は2つ
ここまでの例で、/hello も /add も、
URLは1つなのに、やっていることは2つありました。
最初の表示(GET)
送信後の処理(POST)
これを、ルーティングの視点で整理すると、こうなります。
@app.route("/add", methods=["GET", "POST"])
この1行で、「/add というURLに対して、GET と POST の両方を受け付ける」と宣言している。
関数の中で if request.method == "GET": と分岐することで、
「GETのときはフォームを返す」「POSTのときは計算結果を返す」と役割を分けている。
つまり、
「URLは1つ、メソッドで役割を切り替える」
という設計になっています。
このパターンを理解しておくと、
ログインページ、問い合わせフォーム、投稿フォームなど、
いろんな「入力付きページ」を同じ考え方で作れるようになります。
4日目のミニアプリ:自己紹介+足し算のミニサイト
仕様を言葉でまとめる
トップページ /
名前入力フォーム /hello
足し算フォーム /add
この3つをまとめて、
「Flaskで作る超簡単Webアプリ」のミニサイトにしてみます。
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def index():
return """
<h1>Flask ミニWebアプリ</h1>
<p><a href="/hello">名前あいさつページへ</a></p>
<p><a href="/add">足し算フォームへ</a></p>
"""
@app.route("/hello", methods=["GET", "POST"])
def hello():
if request.method == "GET":
return """
<h1>名前を教えてください</h1>
<form method="post">
<input type="text" name="name" placeholder="お名前">
<button type="submit">送信</button>
</form>
<p><a href="/">トップに戻る</a></p>
"""
name = request.form.get("name", "").strip()
if not name:
return """
<h1>名前が空です</h1>
<p>戻って、名前を入力してください。</p>
<p><a href="/hello">戻る</a></p>
"""
return f"""
<h1>こんにちは、{name} さん!</h1>
<p>フォーム送信ができました。</p>
<p><a href="/hello">もう一度入力する</a></p>
<p><a href="/">トップに戻る</a></p>
"""
@app.route("/add", methods=["GET", "POST"])
def add():
if request.method == "GET":
return """
<h1>足し算フォーム</h1>
<form method="post">
<input type="number" name="a" placeholder="数字A">
<input type="number" name="b" placeholder="数字B">
<button type="submit">計算する</button>
</form>
<p><a href="/">トップに戻る</a></p>
"""
a_str = request.form.get("a", "").strip()
b_str = request.form.get("b", "").strip()
if not a_str or not b_str:
return """
<h1>入力エラー</h1>
<p>AとBの両方に数字を入力してください。</p>
<p><a href="/add">戻る</a></p>
"""
try:
a = float(a_str)
b = float(b_str)
except ValueError:
return """
<h1>入力エラー</h1>
<p>数字として解釈できませんでした。半角の数字を入力してください。</p>
<p><a href="/add">戻る</a></p>
"""
result = a + b
return f"""
<h1>計算結果</h1>
<p>{a} + {b} = {result}</p>
<p><a href="/add">もう一度計算する</a></p>
<p><a href="/">トップに戻る</a></p>
"""
if __name__ == "__main__":
app.run(debug=True)
Pythonこれで、
「トップページ → 名前フォーム → 足し算フォーム」
という流れを、ブラウザの中で行ったり来たりできます。
4日目で絶対に押さえてほしい本質
「同じURLでも、メソッドで役割を切り替える」
今日いちばん大事なのは、
Flaskのルーティングをこう説明できることです。
URLに対して、
どのHTTPメソッド(GET, POST など)を受け付けるかを methods で指定できる。
同じURLでも、
GET のときは「ページを表示する」
POST のときは「フォームの内容を受け取って処理する」
というふうに、役割を分けられる。
フォームから送られてきた値は、request.form.get("名前") で受け取る。
クエリパラメータ(?以降)は request.args、
フォーム(POST)は request.form。
ここまで理解できていれば、
もう「ただの静的なページ」から一歩抜け出して、
「ユーザーの入力を受け取って動くWebアプリ」 を作れる状態になっています。
5日目以降は、
ここに「テンプレートファイル(HTMLを別ファイルに分ける)」や
「リダイレクト」「フラッシュメッセージ」などを重ねていきます。
でも、どれだけ機能が増えても、
今日やった
URL
メソッド(GET / POST)request.args と request.form
同じURLで役割を切り替える if 文
この4つが、ずっと土台であり続けます。

