将表单数组发送到 Flask
Posted
技术标签:
【中文标题】将表单数组发送到 Flask【英文标题】:Sending a form array to Flask 【发布时间】:2014-09-08 15:02:54 【问题描述】:我有一个包含多个输入的 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 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')
。
【讨论】:
如果我的输入是这样的:hello[][some_sub_field]
在发送表单对象数组的表单中?
@RocketPingu:您必须再次提取全名。基本上,在发布到 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=[[1,2]]
或a[[1],[2]]
太难选择了。
所以我建议使用 dict 替换列表:
<input name="hello[0]" type="text" />
<input name="hello[1]" type="text" />
如果你还想发布复杂的数据,我建议你使用application/json
【讨论】:
【参考方案3】:我有一个表单,其中包含一个或两个级别的数组,所以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 个组:首先是“基本”名称,然后是两个级别的名称。如果存在第一级或第二级名称,它将创建一个字典并使用发布的值填充它,然后继续删除原始键/值。
【讨论】:
以上是关于将表单数组发送到 Flask的主要内容,如果未能解决你的问题,请参考以下文章