web-dev-qa-db-fra.com

Envoi d'un tableau de formulaires à Flask

J'ai un formulaire HTML avec plusieurs entrées nommées comme ceci:

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

Dans PHP vous obtenez ceci comme un tableau mais est-ce la même manière en Python, en utilisant Flask?

J'ai essayé ceci:

hello = request.form['hello']

print(hello)

Mais cela n'a pas fonctionné, j'ai obtenu un 400 Bad Request:

Bad Request

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

Comment puis-je le faire dans Flask?

40
theva

Vous suivez une convention PHP d'ajout de crochets aux noms de champs . Ce n'est pas une norme Web, mais parce que PHP le prend en charge dès la sortie de la boîte, il est populaire; Ruby on Rails also l'utilise.

Si vous utilisez cette convention, pour obtenir les données POST du côté Flask, vous devez inclure les crochets dans le nom du champ. Vous pouvez récupérer toutes les valeurs de la liste en utilisant MultiDict.getlist() :

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

Bien sûr, vous n'êtes pas obligé d'utiliser la convention []. Ne pas ajouter le [] Au nom hello fonctionnera parfaitement, auquel cas vous utiliseriez request.form.getlist('hello') dans Flask.

78
Martijn Pieters

J'ai écrit une fonction d'analyse qui prend en charge le dict multidimensionnel: 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

Usage:

>>> 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'}}}

Avertissement: Il ne prend pas en charge la liste, par exemple. a[][0]=1&a[][0]=2, cela peut rendre le programmeur confus. Non plus a=[[1,2]] ou a[[1],[2]] est trop difficile à choisir.

Je suggère donc d'utiliser dict pour remplacer la liste:

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

Si vous souhaitez toujours publier des données complexes, je vous suggère d'utiliser application/json

2
ahuigo