Flaskを使ってみる

FormとTemplate


WEBフレームワークの最も重要な機能はテンプレートに好きな文字を埋め込むレンダリングの機能です。
以下のコードでは、title, text1, text2, text3の4つの変数をテンプレートに渡しています。
複数の変数は、以下の書式でテンプレートに渡すことができます。
・独立した変数
・辞書型(Dictionary)の変数
・list変数
・tuple変数
# -*- coding: utf-8 -*-
from flask import Flask, render_template
app = Flask(__name__)

@app.route("/test1")
def test1():
    return render_template("index1.html", title="test1", text1="aaa", text2="bbb", text3="ccc")

@app.route("/test2")
def test2():
    templateData = {
        'text1' : "aaa",
        'text2' : "bbb",
        'text3' : "ccc"
    }
    return render_template("index1.html", title="test2", **templateData)

@app.route("/test3")
def test3():
    texts = []
    texts.append("aaa")
    texts.append("bbb")
    texts.append("ccc")
    return render_template("index3.html", title="test3", text=texts)

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)~

独立した変数や辞書型で渡した場合、テンプレートでは以下の様に変数名で変数を参照します。
<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        {{ title }}<br>
        {{ text1 }}<br>
        {{ text2 }}<br>
        {{ text3 }}<br>
    </body>
</html>

list変数やtuple変数で渡す場合、テンプレート側では変数名にインデックスを付けて参照します。
<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        {{ title }}<br>
        {{ text[0] }}<br>
        {{ text[1] }}<br>
        {{ text[2] }}<br>
    </body>
</html>

いずれも結果は同じになります。




listの入れ子、あるいはlist構造のtupleをテンプレートに渡すと簡単にテーブルを作ることができます。
listの入れ子を渡す場合、pythonコードは以下の様になります。
# -*- coding: utf-8 -*-
import csv
from flask import Flask, render_template
app = Flask(__name__)

@app.route("/table1")
def table1():
    lists = []

    filename = 'sample.csv'
    with open(filename, encoding='utf8', newline='') as f:
        csvreader = csv.reader(f)
        for row in csvreader:
            print(row)
            print(row[0])

            texts = []
            texts.append(row[0])
            texts.append(row[1])
            texts.append(row[2])
            lists.append(texts)

    return render_template("table1.html", lists=lists)

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)


テンプレート側ではpythonコードを使って2重ループを組みます。
<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        {{ title }}<br>
        <table cellspacing="2" cellpadding="2" border="1"> <tbody>
            <tr>
                <th>西暦</th>
                <th>年号</th>
                <th>人口</th>
            </tr>
            {% for list in lists %}
            <tr>
                {% for item in list %}
                    <td>{{ item }}</td>
                {% endfor %}
            </tr>
            {% endfor %}
        </tbody> </table>
    </body>
</html>

結果はこのようになります。


辞書型の配列をテンプレートに渡すこともできます。
辞書型の配列を渡す場合、pythonコードは以下の様になります。
# -*- coding: utf-8 -*-
import csv
from flask import Flask, render_template
app = Flask(__name__)

@app.route("/table3")
def table3():
    lists = []

    filename = 'sample.csv'
    with open(filename, encoding='utf8', newline='') as f:
        csvreader = csv.reader(f)
        for row in csvreader:
            print(row)
            print(row[0])

            lists.append({
                "year": row[0],
                "era": row[1],
                "population": row[2],
            })

    return render_template("table3.html", lists=lists)

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)


テンプレート側ではpythonコードを使ってループを組みます。
変数名で変数を参照するので、テンプレート側だけで表示する順番を変えることができます。
<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        {{ title }}<br>
        <table cellspacing="2" cellpadding="2" border="1"> <tbody>
            <tr>
                <th>人口</th>
                <th>西暦</th>
                <th>年号</th>
            </tr>
            {% for list in lists %}
            <tr>
                <td>{{ list.population }}</td>
                <td>{{ list.year }}</td>
                <td>{{ list.era }}</td>
            </tr>
            {% endfor %}
        </tbody> </table>
    </body>
</html>

結果はこのようになります。




テンプレートファイル内で変数を扱う方法がこ ちらに公開されていました。
テンプレートファイルの変更だけで行番号を表示することができます。
テンプレート内で row という変数を定義して、ループ内で値をインクリメントしています。
<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        {{ title }}<br>
        <table cellspacing="2" cellpadding="2" border="1"> <tbody>
            <tr>
                <th>西暦</th>
                <th>年号</th>
                <th>人口</th>
            </tr>
            {% set row = namespace(value=0) %}
            {% for list in lists %}
            <tr>
                <td>{{ row.value }}</td>
                {% for item in list %}
                    <td>{{ item }}</td>
                {% endfor %}
            </tr>
            {% set row.value = row.value + 1 %}
            {% endfor %}
        </tbody> </table>
    </body>
</html>

結果はこのようになります。




以下のコードでformに入力した文字を取り出すことができます。
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask(__name__)

@app.route("/")
def get():
    print("get:");
    html = '<html><body><form action="/" method="POST">'
    html = html + "<div>"
    html = html + '<input type="text" name="text1" value="hogehoge">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="text" name="text2" value="fugafuga">'
    html = html + "</div>"
    html = html + '<input type="submit" value="Submit">'
    html = html + '</form></body></html>'
    return html

@app.route("/", methods=['POST'])
def post():
    print("post: request.form={}".format(request.form))
    html = "text1 is " + request.form['text1'] + "<br>"
    html = html + "text2 is " + request.form['text2']
    return html

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)

このコードを実行すると以下のフォームが表示されます。


submitボタンを押すとpost()でデータを受け取ります。




フォーム内に複数のボタンが有る場合、以下のコードでどのボタンが押されたかを判定することができます。
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask(__name__)

@app.route("/")
def get():
    print("get:");
    html = '<html><body><form action="/" method="POST">'
    html = html + "<div>"
    html = html + '<input type="text" name="text1" value="hogehoge">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="text" name="text2" value="fugafuga">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="submit" name="button1" value="Submit1">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="submit" name="button2" value="Submit2">'
    html = html + "</div>"
    html = html + '</form></body></html>'
    return html

@app.route("/", methods=['POST'])
def post():
    print("post: request.form={}".format(request.form))
    if (request.form.get('button1') != None):
        html = "Push " + request.form.get('button1')
    if (request.form.get('button2') != None):
        html = "Push " + request.form.get('button2')
    return html

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)

このコードを実行すると以下のフォームが表示されます。


submitボタンを押すとpost()でデータを受け取り、どのボタンが押されたかを判定します。




フォーム内に複数のチェックボックスが有る場合、以下のコードでどれが選ばれているかを判定することができます。
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask(__name__)

@app.route("/")
def get():
    print("get:");
    html = '<html><body><form action="/" method="POST">'
    html = html + "<div>"
    html = html + '<input type="text" name="text1" value="hogehoge">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="text" name="text2" value="fugafuga">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="checkbox" name="check1" value="Goo">Goo'
    html = html + '<input type="checkbox" name="check2" value="Choki">Choki'
    html = html + '<input type="checkbox" name="check3" value="Paa">Paa'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="submit" value="Submit">'
    html = html + "</div>"
    html = html + '</form></body></html>'
    return html

@app.route("/", methods=['POST'])
def post():
    print("post: request.form={}".format(request.form))
    html = ""
    if (request.form.get('check1') != None):
        html = html + "Select " + request.form.get('check1') + "<br>"
    if (request.form.get('check2') != None):
        html = html + "Select " + request.form.get('check2') + "<br>"
    if (request.form.get('check3') != None):
        html = html + "Select " + request.form.get('check3') + "<br>"
    return html

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)

このコードを実行すると以下のフォームが表示されます。


submitボタンを押すとpost()でデータを受け取り、どのチェックボックスが選択されているかを判定します。




フォーム内のラジオボタンの値を取り出すことができます。
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask(__name__)

@app.route("/")
def get():
    print("get:");
    html = '<html><body><form action="/" method="POST">'
    html = html + "<div>"
    html = html + '<input type="text" name="text1" value="hogehoge">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="text" name="text2" value="fugafuga">'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="radio" name="jyanken" value="Goo" checked="checked">Goo'
    html = html + '<input type="radio" name="jyanken" value="Choki">Choki'
    html = html + '<input type="radio" name="jyanken" value="Paa">Paa'
    html = html + "</div>"
    html = html + "<div>"
    html = html + '<input type="submit" value="Submit">'
    html = html + "</div>"
    html = html + '</form></body></html>'
    return html

@app.route("/", methods=['POST'])
def post():
    print("post: request.form={}".format(request.form))
    html = "Select " + request.form.get('jyanken')
    return html

if __name__ == "__main__":
    #app.run()
    app.run(host='0.0.0.0', port=8000, debug=True)

このコードを実行すると以下のフォームが表示されます。


submitボタンを押すとpost()でデータを受け取り、ラジオボタンの値を取り出します。


続く...