【Flask】基本的なGET/POSTリクエストの方法

概要

flaskを使用した基本的なGET/POSTリクエストの方法についてまとめた。
それぞれの通信にて、画面(HTML)とサーバー(Pythonファイル)間でどのようにデータを受け渡すのかを扱う。

尚、GET/POSTとは何か、またその使い分けについては扱わない。

 

あわせて読みたい

概要 flaskモジュールを使用して簡易的なサーバーをローカルに作成したので、その方法についてまとめる。 flaskとは、PythonのWEBアプリケーションフレームワークの一つ。   flaskの使用方法 ライブラ[…]

【Flask】簡易サーバーを作成する方法
あわせて読みたい

概要 Jinjaテンプレートを使用して、サーバーからの値をHTMLに埋め込む方法についてまとめた。 テンプレートとは、プログラムからデータを渡して動的に文章を作成するためのひながた。 Jinjaテンプレートでは、値を埋め込むだけで[…]

【Flask】Jinjaテンプレートを用いてHTMLへ動的な値を埋め込む方法

 

GETの場合

アンカータグを使用してパラメータを送る

画面遷移

【flaskリクエスト方法】トップ画面

【flaskリクエスト方法】結果画面

 

1番~3番がアンカータグで囲まれたリンクになっている。
リンクのどれかを押下すると、GETリクエストにより指定のURLへ送信する

その際に、パラメータも一緒にサーバー側へ渡す
サーバー側ではGETリクエストにより渡されたパラメータを取得し、結果画面にデータを返却する。

 

画面側

 


<div style="outline: 1px solid black; width:50%; padding: 0.5rem">
    <h5>リンク送信(クエリパラメータ)</h5>
    <p>IDを選択してください。</p>
    <ul>
        <li><a href="/result?id_key=1">1番</a>:冷蔵庫</li>
        <li><a href="/result?id_key=2">2番</a>:洗濯機</li>
        <li><a href="/result?id_key=3">3番</a>:テレビ</li>
    </ul>
</div>

アンカータグのURLに、以下の形式でURLを設定する。

<a href=”URLパス?変数名=値&変数名=値“>XXXXX</a>

「?」以降の「変数名=値」の部分をクエリパラメータクエリストリングとよぶ。
この形式で記述すると、GETリクエストでサーバー側にパラメータを送信できる。

尚、複数のクエリパラメータを送りたい場合、「&」で区切ればOK。

上記の場合、id_keyという変数名にそれぞれ1~3の値を設定している。

 

サーバー側

 


@app.route("/result")
def result():
    """ GETのクエリパラメータを受け取る """
    id_key = request.args.get("id_key", "")
    ID_MAP = {'1': '冷蔵庫', '2': '洗濯機', '3': 'テレビ'}
    return render_template("/sub/result.html", id_result=ID_MAP[id_key])

request.argsに辞書型の形式でクエリパラメータが格納される
そのため、以下のように記述することでクエリパラメータを取得できる。

id_key = request.args.get("id_key", "")

request.args[“変数名”]と記述しても取得は可能だが、取得できない場合はKeyErrorになる

KeyErrorを回避するために、上記のようにgetメソッドを使用して、パラメータを取得できない場合は空文字とするなどの対応が必要。

上記の場合、”id_key”というキーで値を取得できた場合、id_key変数に格納する。
取得できない場合、空文字をid_key変数に格納する。

 

フォームを使用してパラメータを送る

画面遷移

【flaskリクエスト方法】GETのフォーム通信

【flaskリクエスト方法】GETのフォーム通信結果画面

 

テキストボックスに入力した値をクエリパラメータとしてフォーム送信する。
サーバー側ではGETリクエストにより渡されたパラメータを取得し、結果画面にデータを返却する。

 

画面側

 


<h5>フォーム送信</h5>
<div style="outline: 1px solid black; width:50%; padding: 0.5rem">
    <form method="get" action="/result_2">
        <p>名前:<input type="text" name="name" size="40"></p>
        <button type="submit">送信</button>
    </form>
</div>

formタグのmethod属性に「get」を設定することで、GETリクエストにて送信できる。
action属性にはリクエスト送信先のURLを設定する。

クエリパラメータとして送信するパラメータは、form内のテキストボックス。
name属性に定義したnameが変数名になる。

 

サーバー側


@app.route("/result_2")
def result_2():
    """ GETのクエリパラメータを受け取るその2 """
    your_name = request.args.get("name", "")
    return render_template("/sub/result.html", name=your_name)

アンカータグの時と同じように、request.argsに辞書型の形式でクエリパラメータが格納される。
getメソッドに変数名を指定して取得する。

 

POSTの場合

フォームを使用してパラメータを送る

画面遷移

【flaskリクエスト方法】POSTの各種入力フォーム

【flaskリクエスト方法】POSTの各種入力フォーム画面遷移後

 

以下のform部品を入力or設定して送信ボタンを押下する。

・テキストボックス
・テキストエリア
・セレクトボックス
・チェックボックス
・ラジオボタン

サーバー側で送られてきたすべてのform部品から画面入力値を取得し、画面にそのデータを返却する。

 

画面側

 


<div style="outline: 1px solid black; width:50%; padding: 0.5rem">
    <form action="/result_3" method="post">
      <label for="fname">名前(テキストボックス):</label><br>
      <input type="text" id="fname" name="fname"><br><br>
      
      <label for="description">説明(テキストエリア):</label><br>
      <textarea id="description" name="description" rows="4" cols="50"></textarea><br><br>
      
      <label for="cars">車メーカー(セレクトボックス):</label><br>
      <select id="cars" name="cars">
        <option value="1">トヨタ</option>
        <option value="2">ホンダ</option>
        <option value="3">ダイハツ</option>
        <option value="4">スズキ</option>
      </select><br><br>

      <p>ニュースレターを購読(チェックボックス):</p>
      <input type="checkbox" id="subscribe1" name="subscribe1" value="news1">
      <label for="subscribe1">ニュース1</label><br>
      <input type="checkbox" id="subscribe2" name="subscribe2" value="news2">
      <label for="subscribe2">ニュース2</label><br>
      <input type="checkbox" id="subscribe3" name="subscribe3" value="news3">
      <label for="subscribe3">ニュース3</label><br><br>
      
      <p>性別(ラジオボタン):</p>
      <input type="radio" id="male" name="gender" value="male">
      <label for="male">男性</label><br>
      <input type="radio" id="female" name="gender" value="female">
      <label for="female">女性</label><br><br>
      
      <input type="submit" value="送信">
    </form>
</div>

formタグのmethod属性に「post」を設定することで、POSTリクエストにより送信できる。
action属性にはリクエスト送信先のURLを設定する。

 

サーバー側

 


@app.route("/result_3", methods = ["POST"])
def result_3():
    """ POSTのパラメータを受け取る """
    ctx = {}
    # テキストボックス
    ctx["名前"] = request.form["fname"]
    # テキストエリア
    ctx["説明"] = request.form.get("description", "入力なし")
    # セレクトボックス
    ctx["車"] = request.form.get("cars", "入力なし")
    # チェックボックス
    ctx["ニュース1"] = request.form.get("subscribe1", "入力なし")
    ctx["ニュース2"] = request.form.get("subscribe2", "入力なし")
    ctx["ニュース3"] = request.form.get("subscribe3", "入力なし")
    # ラジオボタン
    ctx["性別"] = request.form.get("gender", "入力なし")
    
    return render_template("/sub/result.html", ctx=ctx)

POSTリクエストでパラメータを取得する際には、URLのルーティングする箇所に以下の設定を行う。

@app.route(“/result_3”, methods = [“POST”])

上記を設定をしないと、サーバー側でリクエストを拒否してしまう。

また、パラメータを取得する場合はrequest.formに辞書形式で格納されている
request.form[“辞書キー”]としても取得は可能だが、取得できない場合はKeyErrorになる。
そのため、getメソッドを使用する方がいい。

ただし、テキストボックスとテキストエリアについてはrequest.form[“辞書キー”]で値を取得できていなくてもKeyErrorが発生しなかった。

 

その他

url_for()

url_forメソッドをHTMLテンプレート側で使用することで、サーバー側と疎通できる。
これまでのGET/POSTリクエストのHTML側での記述を、url_forメソッドで書き換えが可能。

また、動的なURL作成にも対応できる。

 

使い方

アンカータグ
<li><a href="/result?id_key=3">3番</a>:テレビ</li>

 

<li><a href="{{ url_for('result', id_key=3) }}">3番</a>:テレビ</li>

url_for()の第一引数にはサーバー側のメソッドを指定する。
第二引数以降にはクエリパラメータを設定可能。

 

フォーム
<form action="/result_3" method="post">

 

<form action="{{ url_for('result_3') }}" method="post">

url_for()の引数にサーバー側のメソッドを指定する。

 

動的なURLを作成する

画面遷移

【flaskリクエスト方法】一覧画面表示

【flaskリクエスト方法】詳細画面

処理の流れ

サーバー側からリストを渡して、画面側で動的に一覧データを表示する。
その際に、ID項目に対してアンカータグを設定する。

アンカータグには動的に取得したIDを設定する。
リンクを押下すると、サーバー側で取得したIDをもとに該当するデータを結果画面に返す。

一般的なECサイトなどで商品一覧をDBから検索して表示した後に、個別の詳細画面を表示するような動き。

 

トップ画面表示処理

画面側

 


<table>
    <tr>
        <th>ID</th>
        <th>名前</th>
        <th>部活</th>
        <th>趣味</th>
    </tr>
    {% for s in students %}
    <tr>
        <td><a href="{{ url_for('result', s_id=s.id) }}">{{ s.id }}</a></td>
        <td>{{ s.name }}</td>
        <td>{{ s.bukatu }}</td>
        <td>{{ s.hobby }}</td>
    </tr>
    {% endfor %}
</table>

 

    {% for s in students %}
    <tr>
        <td><a href="{{ url_for('result', s_id=s.id) }}">{{ s.id }}</a></td>
        <td>{{ s.name }}</td>
        <td>{{ s.bukatu }}</td>
        <td>{{ s.hobby }}</td>
    </tr>
    {% endfor %}

画面側ではstudentsリストを受け取り、Studentオブジェクトをループする。
url_for関数のクエリパラメータにs_idという変数でStudentオブジェクトのid属性を設定する。

これにより、サーバー側へs_idという変数でパラメータを動的に設定して送信する。

 

サーバー側

 


# 学生情報
class Student:
    def __init__(self, id, name, bukatu, hobby):
        self.id = id
        self.name = name
        self.bukatu = bukatu
        self.hobby = hobby
# 学生情報リスト
STUDENTS = [
    Student(1, "山田", "野球部", "映画鑑賞"),
    Student(2, "佐藤", "サッカー部", "お笑い鑑賞"),
    Student(3, "園田", "茶道部", "手芸")
]

@app.route("/")
def index():
    """ トップ画面表示 """
    return render_template("/sub2/index.html", students=STUDENTS)

初期画面を表示する際に、Studentクラスのリストを画面側に渡している。
id、name、bukatu、hobby属性を保持している。

 

リンク押下後、結果画面表示処理

画面側

 


<body>
    <p>ID: {{ student.id }}</p>
    <p>名前: {{ student.name }}</p>
    <p>部活: {{ student.bukatu }}</p>
    <p>趣味: {{ student.hobby }}</p>
    <p><a href="/">戻る</a></p>
</body>

サーバー側から渡されたStudentクラスの情報を表示する。

 

サーバー側

 


@app.route("/res/<s_id>")
def result(s_id):
    for s in STUDENTS:
        if s.id == int(s_id):
        res = s
        return render_template("/sub2/result.html", student=res)

動的なクエリパラメータを受け取る場合、以下のように記述する。

@app.route(“/res/<s_id>“)
def result(s_id):
    for s in STUDENTS:
        if s.id == int(s_id):
        (略)

上記赤文字箇所の変数名は、HTMLテンプレート側のurl_forメソッドにて指定したクエリパラメータの変数名を設定する。
上記のように記述することで、画面側から動的に設定したパラメータを取得することができる。

スポンサーリンク