126
105

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

はじめての Flask #2 ~POSTを受け取ろう~

Last updated at Posted at 2018-05-20

前回: ~はじめてのウェブアプリ~

今回は、ページからのPOSTを受け取って、動的にページを作成しようと思います。

ここを理解すれば、フォームもあらかた理解できるでしょう。

#formを作ろう!

Flaskでページを出力するにはいくつか方法があり、

  • return で文字列(html)を返す
  • render_template でtemplatesフォルダー内のhtmlファイルを返す

の二つが主な手法です。今回は少ないコードで済むので、1番目を採用しましょう。

return "html内部"

という風に返します。

##ここで少しhtmlのお勉強
htmlでフォームを表現するには、**<form>**タグを使います。

また、このタグにはactionmethodパラメータをつけましょう。(methodは必須ではありません)

actionタグではデータを送信する先を指定し、methodでは送り方を決めます。methodには2種類あり、それぞれ**"GET""POST"**です。
GETはurlに直接データをねじ込みます。

http://url_for_taget/?key=value

の様になります。

ですが、POSTではURLからはデータの内容は分かりません。直接見れない形でデータが送られるからです。この解析には、fiddlerなどのツールを用います。

今回は、これを使います。

また、フォームの中には送るデータを入力させなければいけません。今回は、inputフィールドを使用しましょう。

また、flask側でpostを解析するためにinputにnameをつけなければいけませんので、それも忘れずに!

#実装

現段階をまとめると

from flask import *

app = Flask(__name__)


@app.route("/")
def odd_even():
        return """
        下に整数を入力してください。奇数か偶数か判定します
        <form action="/" method="POST">
        <input name="num"></input>
        </form>"""

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

の様になります。

では、データが送られてきた後の動作を実装しましょう!

まず、POSTを受け取れるように変更しましょう。

from flask import *

app = Flask(__name__)


@app.route("/", methods=["GET", "POST"])
def odd_even():
        return """
        下に整数を入力してください。奇数か偶数か判定します
        <form action="/" method="POST">
        <input name="num"></input>
        </form>"""

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

app.route に methodsが増えましたね。これで、POSTとGETの二つのメソッドを許可できました。標準ではGETのみになっています。

これをしないでPOSTすると、"そんな方式は受け取れないよ!"とエラーを吐かれます

次に、GETの時(普通に接続されたとき)とPOSTの時(データを送られたとき)の動作を分けて、POSTの時の動作を付け加えましょう!

from flask import *

app = Flask(__name__)


@app.route("/", methods=["GET", "POST"])
def odd_even():
    if request.method == "GET":
        return """
        下に整数を入力してください。奇数か偶数か判定します
        <form action="/" method="POST">
        <input name="num"></input>
        </form>"""
    else:
        return """
        {}は{}です!
        <form action="/" method="POST">
        <input name="num"></input>
        </form>""".format(str(request.form["num"]), ["偶数", "奇数"][int(request.form["num"]) % 2])

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

Flaskには、ページへの接続方式を探知する機能があります。

それは、request.methodです。
GETかPOSTを返します。

また、formのデータをうけとるのにrequest.formを使えます。ディクショナリで、key(name)とvalue(データ)をくれます。

ですので、request.form["num"]とすると、formの中のnameがnumのデータを取り出せます。
ただ、inputで得られるデータは文字列ですので、気を付けなければいけません。

数字でない文字列を与えられたときのエラーを出力するページも作りましょう

from flask import *

app = Flask(__name__)


@app.route("/", methods=["GET", "POST"])
def odd_even():
    if request.method == "GET":
        return """
        下に整数を入力してください。奇数か偶数か判定します
        <form action="/" method="POST">
        <input name="num"></input>
        </form>"""
    else:
        try:
            return """
            {}は{}です!
            <form action="/" method="POST">
            <input name="num"></input>
            </form>""".format(str(request.form["num"]), ["偶数", "奇数"][int(request.form["num"]) % 2])
        except:
            return """
                    有効な数字ではありません!入力しなおしてください。
                    <form action="/" method="POST">
                    <input name="num"></input>
                    </form>"""


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

try-exceptで十分でしょう。

実行してみてください。これで、奇数偶数判定プログラムができましたね!

少し変えるだけで、BMIを計算したり、素数判定をしたり、数あてゲームをしたり… いろいろできそうですよね!

次回はhtmlファイルとjinja2を使ってrenderしてみましょう!

126
105
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
126
105

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?