前提条件
┣ app.py
︙
┗ templates/
┗ index.html
ターミナル(コマンドプロンプト)のカレントディレクトリは、 flaskフォルダにあるものとします。
app.py
# -*- coding: utf-8 -*-
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run()
index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello Jinja2</title>
</head>
<body>
<h1>Hello Jinja2</h1>
<p>Jinja2でHTMLファイルを読み込みことに成功しました。</p>
</body>
</html>
1次元配列を受け取る
<form action="/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="arr" value="[1,2,3,4,5]"> <!-- 文字列として送信される -->
<input type="submit" value="送信">
</form>
HTMLのform
要素で配列を直接送ることはできません。
では、どうするか
サーバーサイドで1次元配列風の文字列を受け取って、それをPythonの1次元配列に無理やり変換させます。
具体的には、文字列として受け取った1次元配列を正規表現(re
モジュールのsub
メソッド)でカッコや空白文字を取り除いて、標準の組み込み関数のsplit
メソッドで文字列を配列に変換します。
from flask import Flask, render_template, request
import re
# 1次元配列風の文字列をフォームから受け取る
str1 = request.form.get('arr')
# 文字列→1次元配列
arr1 = re.sub('(\[|\'|\]|\s)', '', str1).split(',')
サンプルプログラム
<!-- 中略 -->
<body>
{%- set arr = [1,2,3,4,5] %}
<form action="/" method="POST" enctype="multipart/form-data">
<input type="hidden" id="arr" name="arr" value="{{ arr }}">
<input type="submit" value="送信">
</form>
</body>
# 中略
@app.route('/', methods=['POST'])
def post():
# 1次元配列風の文字列をフォームから受け取る
str1 = request.form.get('arr')
# 文字列→1次元配列
arr1 = re.sub('(\[|\'|\]|\s)', '', str1).split(',')
print("arr1", arr1, type(arr1)) # ここでチェック
# => arr1 ['1', '2', '3', '4', '5']
2次元配列を受け取る
<form action="/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="arr" value="[[1,2,3],['a','b','c'],['あ','い','う']]">
<input type="submit" value="送信">
</form>
1次元配列のときと同様に、HTMLのform
要素で配列を直接送ることはできません。
考え方も同じで、サーバーサイドで2次元配列風の文字列を受け取って、それをPythonの2次元配列に無理やり変換させます。
from flask import Flask, render_template, request
import re
# 2次元配列風の文字列をフォームから受け取る
str2 = request.form.get('arr')
# 文字列→2次元配列?
arr2 = re.sub('(\[|\'|\]|\s)', '', str2).split(',')
しかし、残念ながら、この方法だと1次元配列が生成されてしまいます。
print(arr2)
# => ['1', '2', '3', 'a', 'b', 'c', 'あ', 'い', 'う']
この配列でいうと3つの要素ごとに句切れば、欲しい2次元配列が取得することができますね。
from flask import Flask, render_template, request
import re
# 2次元配列風の文字列をフォームから受け取る
str2 = request.form.get('arr')
# 文字列→1次元配列
arr1 = re.sub('(\[|\'|\]|\s)', '', str2).split(',')
# 区切り文字数
n = 3
# 1次元配列→2次元配列
arr2 = [arr1 [i:i + n] for i in range(0, len(arr1), n)]
print(arr2)
# => [['1', '2', '3'], ['a', 'b', 'c'], ['あ', 'い', 'う']]
この方法で、2次元配列風の文字列をフォームから受け取って、2次元配列に変換することに成功しましたが、区切り文字数をn = 3
と手動で設定しているところが汎用性が低いので、ここも計算させましょう。
この値はクライアントサイド側(Jinja2)のlength
フィルターで求めると簡単です。
サンプルプログラム
<!-- 中略 -->
<body>
{%- set arr = [[1,2,3],['a','b','c'],['あ','い','う']] %}
<form action="/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="arr" value="{{ arr }}">
<input type="hidden" name="num" value="{{ arr[0]|length }}">
<input type="submit" value="送信">
</form>
</body>
# 中略
@app.route('/', methods=['POST'])
def post():
# 2次元配列風の文字列をフォームから受け取る
str2 = request.form.get('arr')
# 文字列→1次元配列
arr1 = re.sub('(\[|\'|\]|\s)', '', str2).split(',')
# 区切り文字数をフォームから受け取る
n = int(request.form.get('num'))
# 1次元配列→2次元配列
arr2 = [arr1 [i:i + n] for i in range(0, len(arr1), n)]
print("arr2", arr2, type(arr2))
# => arr2 [['1', '2', '3'], ['a', 'b', 'c'], ['あ', 'い', 'う']]
連載目次:FlaskでWebアプリケーションを開発するためのロードマップ
入門編:10記事
入門編の10記事を順に読んでいけば、FlaskでWebアプリケーションを開発する必要最小限のことが学べます。
簡単なアプリケーションであれば、セキュリティ上の観点を考慮しなかった場合公開できるでしょう。
- Flaskを『ローカルで開発する環境構築』から『プログラムの実行まで』を一通り
FlaskでWebアプリケーションを作る『全体の流れ』を大まかに理解する- Flaskのrender_templateでHTML・CSS・JavaScriptファイルを読み込む
- サーバーサイドからクライアントサイドに変数(値・リスト・辞書型配列)を渡す
- クライアントサイドで変数を処理(アサイン、フィルター、エスケープ)する
- クライアントサイドで条件分岐(if)とループ(for in)を使って、コードを簡素化する
- クライアントサイド(form)からサーバーサイドにテキストや各種コントロール、ファイルを渡す
- テンプレート継承でHTMLファイルを役割ごとに分割する
データベースに接続するデプロイする
実践編
実践編の記事では、FlaskでWebアプリケーションを公開するために欠かせないセキュリティのことや実践的なテクニックを紹介しています。
ここまで読み込めば、あとはアイディア次第でいろんなWebアプリケーションを公開できるでしょう!
セッションCookieメソッドベース・ディスパッチベーシック認証・Digest認証ログイン機能- サーバーサイドからクライアントサイドにpandas.Series、pandas.DataFrameを渡す
- クライアントサイド(form)からPOSTされた1、2次元配列を受け取る
matplotlibを使うBootstrap4を使うフォームの非同期通信(Ajax, jQuery)