我有一个HTML表单,其中包含多个输入,如下所示:
<input name="hello[]" type="text" />
<input name="hello[]" type="text" />
<input name="hello[]" type="text" />
在 PHP 中,您可以将其作为数组获得,但在使用Flask的情况下,它是否与Python相同?
我试过这个:
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中进行操作?
答案 0 :(得分:75)
您正在关注PHP convention of adding brackets to the field names。它不是一个Web标准,但因为PHP支持它开箱即用,它很受欢迎; Ruby on Rails也使用它。
如果您确实使用该约定,要在Flask端获取POST数据,您需要在字段名称中包含方括号。您可以使用MultiDict.getlist()
hello = request.form.getlist('hello[]')
当然,您根本不必使用[]
惯例。不将[]
附加到hello
名称将完全正常,此时您将在Flask中使用request.form.getlist('hello')
。
答案 1 :(得分:1)
我编写了一个支持多维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替换list:
<input name="hello[0]" type="text" />
<input name="hello[1]" type="text" />
如果您仍想发布复杂数据,建议您使用application/json
答案 2 :(得分:0)
我有一个表单,该表单具有一个或两个级别的数组,所以a[1]
或b[1][2]
。
我已经编写了一个正则表达式解决方案,以将其与发布的数据一起应用到字典中。
import re
re_post = re.compile(r'([a-z_]*)(\[(.*?)\])?(\[(.*?)\])?')
for post_key, post_value in request.form.copy().items():
matches = list(re_post.findall(post_key)[0][0::2])
if matches[1]:
request.form.setdefault(matches[0], {})
if matches[2]:
request.form[matches[0]].setdefault(matches[1], {})
request.form[matches[0]][matches[1]][matches[2]] = post_value
else:
request.form[matches[0]][matches[1]] = post_value
else:
continue
del request.form[post_key]
因此它遍历表单键/值并匹配键中的3组:首先是“基本”名称,然后是两个级别的名称。如果存在第一级或第二级名称,它将创建一个字典,并用发布的值填充它,然后继续删除原始键/值。