FlaskでGETリクエストのクエリパラメータを取得する

クエリパラメータは、クエリ文字列の一部で、パラメータのキーと値のペアを含むURLのセクションである。

通常、パラメータはGETリクエストと一緒に送信され、操作のフィルタをさらに指定します。

www.example.com/search?name=John&location=Miami


パラメータは ? 文字の後に定義され、各キーと値のペアは & で区切られます。

スペースは %20 として表現され、また + として表現することもできます。

これらはキー-バリューのセットにマッピングされる。

name=John
location=Miami


JavaScriptでURLを操作するのは簡単なので、検索時のフィルタとしてクエリパラメータを追加することが多くなっています。

また、リクエストの本文ではなく、再現性のあるパラメータをもとに画面上のコンテンツを調整することで、パラメータ付きのリンクを送るだけでユーザー間で結果を共有することができます!(※)。

例えば、AirBnBの場合、場所や日時を自由に設定し、オートサジェストを希望すれば、ボタンをクリックするだけで、次のようなサイトが表示されます。

https://www.airbnb.com/s/homes?refinement_paths%5B%5D=%2Fhomes&date_picker_type=flexible_dates&search_mode=flex_destinations_search&search_type=AUTOSUGGEST


ここでは、refinement_pathsdate_picker_typesearch_modesearch_typeなどのパラメータがあり、それぞれに値が設定されています。

この短いガイドでは、FlaskでGETリクエストのクエリパラメータを取得する方法について見ていきます。

Flaskでクエリパラメータを取得する

from flask import Flask, request
# ...
@app.route('/search', methods=['GET'])
def search():
    args = request.args
    return args


request.argsフィールドはImmutableMultiDict` である。

print(type(args))
# <class 'werkzeug.datastructures.immutablemultidict'=""


によって、簡単に通常の辞書に変換することができる。

print(type(args.to_dict()))
# <class 'dict'=""


さらに、get() メソッドで辞書内の特定のキーを検索することができ、キーが事前に設定した引数リストと一致しない場合はエラーを返します。

print(args.get("name"))
# John


さらに、値を取得する際に intstr などの異なる型にキャストすることができます。

また、値がすでに存在しない場合は、デフォルト値を設定することができる。

例えば、 name パラメータはおそらく文字列になりますが、 price パラメータは整数になるかもしれません。

args.get("name", default="", type=str)
args.get("price", default=0, type=int)


存在しないキーを検索した場合、 None が返されます。

このように、クエリパラメータが存在しないかどうかを確認し、デフォルト値を割り当てるか、あるいは単に使用しないか、といった対応をとることができます。

namelocation` を指定して、エンドポイントに GET リクエストを送信してみましょう。

$ curl "localhost:5000/search?name=John&amp;location=Miami"


この結果、以下のようになります。

{"location":"Miami","name":"John"}


クエリパラメータがNoneでないかのチェック

パラメータを操作するとき、通常は None であるかどうかをチェックして、それに応じて動作させたいと思うでしょう。

ユーザーとその場所の辞書だけのモックデータベースを作りましょう。

そして、URLで渡されたパラメータに基づいて、この辞書をフィルタリングして、パラメータで定義された基準に適合するユーザーを返します。

from flask import Flask, request
# ...
db_users = {
    "John" : "Miami",
    "David" : "Miami",
    "Jane" : "London",
    "Gabriella" : "Paris",
    "Tanaka" : "Tokyo"
}


@app.route('/search', methods=['GET'])
def search():
    args = request.args
    name = args.get('name')
    location = args.get('location')


# result = db_users
    if None not in (name, location):
        result = {key: value for key, value in db_users.items() if key == name and value == location}
    elif name is not None:
        result = {key: value for key, value in db_users.items() if key == name}
    elif location is not None:
        result = {key: value for key, value in db_users.items() if value == location}


return result


ここでは、パラメータリストから namelocation を抽出しています。

もし何もない場合は、すべてのユーザーを返すか、まったく返さないかを選択できます。

もし、すべてのユーザーを取得したい場合は、 result = db_users の行をアンコメントしてください。

namelocationの両方が存在する場合は、両方のパラメータでdb_users` をフィルタリングします。

もし、どちらか一方しか存在しない場合は、存在する方のパラメータだけでフィルタリングを行います。

これで、両方または片方のパラメータを指定して GET リクエストを送信すると、次のように表示されるようになります。

$ curl "localhost:5000/search?name=John&amp;location=Miami"
{"John":"Miami"}


$ curl "localhost:5000/search?name=John"
{"John":"Miami"}


$ curl "localhost:5000/search?location=Miami"
{"David":"Miami","John":"Miami"}


2人がMiamiにいるので、single検索パラメータを使うだけで2人のユーザが見つかります。

ディクショナリにはJohnが1人しかいないので、最初の2つのクエリではJohnだけが返されます。

結論

このガイドでは、Flask で HTTP GET リクエストのクエリパラメータを取得する方法について見てきました。

また、パラメータが None かどうかを確認する方法と、モックデータベースでパラメータがないことを処理する方法について見てきました。

タイトルとURLをコピーしました