クエリパラメータは、クエリ文字列の一部で、パラメータのキーと値のペアを含む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_paths
、date_picker_type
、search_mode
、search_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
さらに、値を取得する際に int
や str
などの異なる型にキャストすることができます。
また、値がすでに存在しない場合は、デフォルト値を設定することができる。
例えば、 name
パラメータはおそらく文字列になりますが、 price
パラメータは整数になるかもしれません。
args.get("name", default="", type=str)
args.get("price", default=0, type=int)
存在しないキーを検索した場合、 None
が返されます。
このように、クエリパラメータが存在しないかどうかを確認し、デフォルト値を割り当てるか、あるいは単に使用しないか、といった対応をとることができます。
nameと
location` を指定して、エンドポイントに GET リクエストを送信してみましょう。
$ curl "localhost:5000/search?name=John&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
ここでは、パラメータリストから name
と location
を抽出しています。
もし何もない場合は、すべてのユーザーを返すか、まったく返さないかを選択できます。
もし、すべてのユーザーを取得したい場合は、 result = db_users
の行をアンコメントしてください。
nameと
locationの両方が存在する場合は、両方のパラメータで
db_users` をフィルタリングします。
もし、どちらか一方しか存在しない場合は、存在する方のパラメータだけでフィルタリングを行います。
これで、両方または片方のパラメータを指定して GET リクエストを送信すると、次のように表示されるようになります。
$ curl "localhost:5000/search?name=John&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
かどうかを確認する方法と、モックデータベースでパラメータがないことを処理する方法について見てきました。