将表单数组发送到 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&amp;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的主要内容,如果未能解决你的问题,请参考以下文章

如何将字节数组中的图像发送到从android到具有Flask的python的url [重复]

将数据从文本框发送到 Flask?

将 HTML 表单数据数组发送到 JSP/Servlet

如何将html表单中的数组发送到php

是否可以在不使用表单的情况下将数组从树枝发送到控制器?

在laravel中使用ajax将多个数组发送到控制器