Отправка массива форм в 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?
Ответы
Ответ 1
Вы следуете соглашению PHP о добавлении скобок к именам полей. Это не веб-стандарт, а потому, что PHP поддерживает его из коробки, он популярен; Ruby on Rails также использует его.
Если вы используете это соглашение, чтобы получить данные POST на стороне Flask, вам нужно включить квадратные скобки в поле. Вы можете получить все значения списка, используя MultiDict.getlist()
:
hello = request.form.getlist('hello[]')
Конечно, вам не обязательно использовать соглашение []
. Не добавление имени []
в hello
будет работать отлично, после чего вы будете использовать request.form.getlist('hello')
в Flask.
Ответ 2
Я написал функцию разбора, которая поддерживает многомерный 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 a=[[1,2]]
или a[[1],[2]]
слишком сложно выбрать.
Поэтому я предлагаю использовать dict для замены списка:
<input name="hello[0]" type="text" />
<input name="hello[1]" type="text" />
Если вы все еще хотите опубликовать сложные данные, я предлагаю вам использовать application/json