web-dev-qa-db-ja.com

フォーム配列をFlaskに送信する

次のような名前の複数の入力を持つHTMLフォームがあります。

<input name="hello[]" type="text" />
<input name="hello[]" type="text" />
<input name="hello[]" type="text" />

[〜#〜] php [〜#〜]では、これを配列として取得しますが、PythonでFlaskを使用するのと同じ方法ですか。

私はこれを試しました:

hello = request.form['hello']

print(hello)

しかし、それはうまくいきませんでした、400 Bad Request

Bad Request

The browser (or proxy) sent a request that this server could not understand.

Flaskでどのように行うのですか?

40
theva

フィールド名に括弧を追加するPHPの規則 に従っています。これはWeb標準ではありませんが、PHPはそのまま使用できるので人気があります; Ruby on Railsもそれを使用します。

この規則を使用する場合、POSTデータをFlask側で取得するには、includeフィールド名の角括弧リストのall値を取得するには MultiDict.getlist()

_hello = request.form.getlist('hello[]')
_

もちろん、_[]_規則を使用する必要はまったくありません。 _[]_をhelloの名前に追加しなくても、Flaskでrequest.form.getlist('hello')を使用することで完全に機能します。

78
Martijn Pieters

多次元dict:php_post=parse_multi_form(request.form)をサポートする解析関数を書きました

def parse_multi_form(form):
    data = {}
    for url_k in form:
        v = form[url_k]
        ks = []
        while url_k:
            if '[' in url_k:
                k, r = url_k.split('[', 1)
                ks.append(k)
                if r[0] == ']':
                    ks.append('')
                url_k = r.replace(']', '', 1)
            else:
                ks.append(url_k)
                break
        sub_data = data
        for i, k in enumerate(ks):
            if k.isdigit():
                k = int(k)
            if i+1 < len(ks):
                if not isinstance(sub_data, dict):
                    break
                if k in sub_data:
                    sub_data = sub_data[k]
                else:
                    sub_data[k] = {}
                    sub_data = sub_data[k]
            else:
                if isinstance(sub_data, dict):
                    sub_data[k] = v

    return data

使用法:

>>> request.form={"a[0][name]": "ahui", "a[0][sex]": "female", "a[1][name]": "bhui", "a[1][sex]": "male"}
>>> parse_multi_form(request.form)
{'a': {0: {'name': 'ahui', 'sex': 'female'}, 1: {'name': 'bhui', 'sex': 'male'}}}

警告:リストをサポートしていません。 a[][0]=1&a[][0]=2、プログラマを混乱させる可能性があります。 a=[[1,2]]またはa[[1],[2]]は選択が難しい。

リストを置き換えるためにdictを使用することをお勧めします:

<input name="hello[0]" type="text" />
<input name="hello[1]" type="text" />

それでも複雑なデータを投稿したい場合は、application/json

2
ahuigo