はじめに
Flask入門パート④です。
前回はrender_templateについて学びました。
前回の記事はこちら
フォームでデータを送信する
今回は今まで学んだことを活用しつつ、ブラウザから値を入力 → 表示ができるようにしたいと思います。
基本的には今まで学んだ内容+少しのHTMLの知識があればデータの送信とそれに対応した処理を作成することができます。
まずは、データを送信するページを作成します。
下記では自身のプロフィール(氏名,年齢,性別)を入力するフォームを作成して、データを送信します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Personal</title>
</head>
<body>
<h1>プロフィール情報</h1>
<form action="{{ url_for('result') }}" method="post">
<label for="username">氏名:</label>
<input type="text" name="username" id="username" required><br>
<label for="age">年齢:</label>
<input type="number" name="age" id="age" required><br>
<label for="sex">性別:</label>
<select name="sex" id="sex">
<option value="man">男性</option>
<option value="woman">女性</option>
<option value="other">その他</option>
</select><br>
<input type="submit" value="登録">
</form>
</body>
</html>
formの動作として、/result/にPOSTメソッドを使用して通信を行うようにしています。
<form action="{{ url_for('result') }}" method="post">
Pythonファイルは以下です。
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route("/personal/", methods=["GET"])
def login():
return render_template("personal.html")
@app.route("/result/", methods=["POST"])
def result():
username = request.form["username"]
age = request.form["age"]
sex = request.form["sex"]
return f"<p>入力された情報を表示します。</p>氏名:{username} </br>年齢:{age}</br>性別:{sex}"
/personal/にGETでアクセスがあった際は、先ほどのHTMLファイルを表示します。
そして、フォームからPOSTメソッドで/result/にアクセスがきたら、入力された情報を表示するようにしています。
request.form[]によって、指定した値の要素を取得できます。
ブラウザから動作確認すると以下のようになります。
-
http://localhost:5000/personal/ へアクセスして情報を記載したのち、登録をクリック

これで、フォームによるデータ送信とその値の取得は完了です。
性別のみ英語表記となっていますが、こちらはselectタグ配下のoptionのvalueを英語にしているためです。
<select name="sex" id="sex">
<option value="man">男性</option>
<option value="woman">女性</option>
<option value="other">その他</option>
</select>
他と合わせる形で日本語にする場合は、テンプレート側で対応(jinja2のif)したり、Python側でマッピングさせたりするとよいかなと思います。
ファイルのアップロード
request.files[]を使用することで、ブラウザからアップロードしたファイルを保存することができます。
サンプルコードは以下の通りです。
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 5 * 1024 * 1024
@app.route("/upload/", methods=["GET", "POST"])
def upload():
if request.method == "GET":
return render_template("upload.html")
else:
f = request.files["upload"]
if f:
f.save(f"/tmp/{secure_filename(f.filename)}")
return render_template("upload.html")
/upload/にGETでアクセスが来た場合は、upload.htmlを表示します。
POSTでアクセスが来た際は、アップロードされたファイルを/tmp/に保存したうえで、upload.htmlを表示します。
なお、アップロード可能なファイルは5MBまでに制限をかけています。
HTMLファイルは下記です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>upload</title>
</head>
<body>
<h1>ファイルアップロード</h1>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="upload" id="upload"><br>
<input type="submit" value="アップロード">
</form>
</body>
</html>
ファイルのアップロードにはformタグにenctype="multipart/form-data"をつけるようにしましょう。
ブラウザから見るとこんな感じです。

ファイルの選択し、アップロードを押下することでサーバ側にファイルを保存する流れができました。
まとめ
今回はデータの送信方法について学びました。
最初と比べると複雑なことができてきましたが、HTMLなどのフロントエンド側の知識も必要になってきました。
1つのWebアプリ作成には多くの知識が必要になることを実感しました。
