前回(pythonの値をhtmlに埋め込む)はPython→HTMLの一方向でした。今回は逆に、ブラウザのフォームからFlaskへ値を送る方法を、GETとPOSTの2通りで作ります。これができると「入力フォームのあるWebアプリ」が作れるようになります。
GETとPOSTの違い
| GET | POST | |
|---|---|---|
| 値の送り先 | URLの末尾(?name=ゾンビ) |
リクエストの本文(URLに出ない) |
| 見える場所 | アドレスバーに丸見え | 見えない |
| 主な用途 | 検索・絞り込みなど | ログイン・登録・送信など |
| Flask側の取得 | request.args.get("name") |
request.form.get("name") |
ざっくり言うと、人に見られて困らない値はGET、パスワードなど見られたくない値はPOSTです。
コード
app.py
request をインポートして使うのがポイントです。
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route("/")
def index():
# (前章までのトップページ。ここでは省略)
...
# GET と POST の両方を1つのルートで受け取る
# methods=['GET', 'POST'] でGET/POSTの両方を許可する
# (GETだけ受け取るなら methods=['GET'] のようにする)
@app.route("/test", methods=["GET", "POST"])
def test():
value = None
if request.method == "POST":
# POSTの値は request.form から取り出す
value = request.form.get("post_value")
else:
# GETの値は request.args から取り出す
value = request.args.get("get_value")
return render_template("form.html", value=value)
ポイントは次のとおりです。
-
/testひとつのルートでmethods=["GET", "POST"]を指定し、GET/POST両方を受ける -
request.methodで今回がGETかPOSTかを判定して、取り出し先を切り替える -
GET の値は
request.args.get("get_value")(URLの?get_value=...) -
POST の値は
request.form.get("post_value")(本文。URLには出ない)
templates/form.html
ボタンを2つ用意し、片方はGET、もう片方はPOSTで同じ /test にリクエストを送ります。
{# GETで /test にリクエストを送るボタン。値はURLの ?get_value=... に付く #}
<form action="/test" method="get">
<button name="get_value" value="from get">get submit</button>
</form>
{# POSTで /test にリクエストを送るボタン。値はURLに出ず本文で送られる #}
<form action="/test" method="post">
<button name="post_value" value="from post">post submit</button>
</form>
{# 受け取った値があれば表示する #}
{% if value %}
<p>受け取った値: {{ value }}</p>
{% endif %}
<button> の name(get_value / post_value)と value(from get / from post)が、そのままFlask側で受け取るキーと値になります。<form> の method 属性(get / post)で送信方法が決まります。
実行と確認
ボタン送信はcurlで再現できます。
# 初期表示(値なし)→ ボタンが2つ表示されるだけ
$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:5000/test
200
# get submit を再現(URLに ?get_value=... が付く)
$ curl -s "http://localhost:5000/test?get_value=from+get" | grep 受け取った
<p>受け取った値: from get</p>
# post submit を再現(本文で送る)
$ curl -s -X POST -d "post_value=from post" http://localhost:5000/test | grep 受け取った
<p>受け取った値: from post</p>
ブラウザで http://localhost:5000/test を開いて各ボタンを押すと、
- get submit … アドレスバーが
/test?get_value=from+getに変わる(値がURLに見える) - post submit … URLは
/testのまま(値はURLに出ない)
という違いが体感できます。
まとめ
- ブラウザ→Flaskへ値を送るにはGETとPOSTがある
- 1つのルートに
methods=["GET", "POST"]を付け、request.methodで分岐する - GETは
request.args.get、POSTはrequest.form.getで受け取る -
<button name="...">のnameがFlask側の取得キーになる - これでFlask入門シリーズは一区切り。フォーム送信ができれば簡単なWebアプリが作れます