web-dev-qa-db-fra.com

Comment utiliser une liste de champs WTForms de FormFields?

Je crée un site Web en utilisant Flask dans lequel j'utilise WTForms . Dans un formulaire, je veux maintenant utiliser une FieldList de FormFields comme suit:

class LocationForm(Form):
    location_id = StringField('location_id')
    city = StringField('city')

class CompanyForm(Form):
    company_name = StringField('company_name')
    locations = FieldList(FormField(LocationForm))

donc pour donner aux gens la possibilité d'entrer dans une entreprise avec deux emplacements (l'ajout dynamique d'emplacements vient plus tard), je fais cela sur la face avant:

<form action="" method="post" role="form">
    {{ companyForm.hidden_tag() }}
    {{ companyForm.company_name() }}
    {{ locationForm.location_id() }}
    {{ locationForm.city() }}
    {{ locationForm.location_id() }}
    {{ locationForm.city() }}
    <input type="submit" value="Submit!" />
</form>

Donc, sur soumettre, j'imprime les emplacements:

print companyForm.locations.data

mais je reçois

[{'location_id': u'', 'city': u''}]

Je peux imprimer les valeurs du premier emplacement à l'aide de locationForm (voir ci-dessous), mais je ne sais toujours pas comment obtenir les données du deuxième emplacement.

print locationForm.location_id.data
print locationForm.city.data

La liste des emplacements a donc un dict avec des valeurs vides, mais:

  1. Pourquoi la liste des lieux n'a-t-elle qu'un et non deux dict?
  2. Et pourquoi les valeurs de l'emplacement dict sont-elles vides?

Quelqu'un sait-il ce que je fais mal ici? Tous les conseils sont les bienvenus!

17
kramer65

Pour commencer, il y a un argument pour FieldList appelé min_entries, Qui fera de la place pour vos données:

class CompanyForm(Form):
    company_name = StringField('company_name')
    locations = FieldList(FormField(LocationForm), min_entries=2)

Cela configurera la liste comme vous le souhaitez. Ensuite, vous devez rendre les champs directement à partir de la propriété locations, afin que les noms soient générés correctement:

<form action="" method="post" role="form">
    {{ companyForm.hidden_tag() }}
    {{ companyForm.company_name() }}
    {{ companyForm.locations() }}
    <input type="submit" value="Submit!" />
</form>

Regardez le code HTML rendu, les entrées doivent avoir des noms comme locations-0-city, De cette façon, WTForms saura qui est lequel.

Alternativement, pour le rendu personnalisé des éléments,

{% for l in companyForms.locations %}
{{ l.form.city }}
{% endfor %}

(dans wtforms seul l.city est un raccourci pour l.form.city. Cependant, cette syntaxe semble entrer en conflit avec Jinja, et là, il est nécessaire d'utiliser explicitement l.form.city dans le modèle.)

Maintenant, pour préparer les données soumises, créez simplement le CompanyForm et parcourez les emplacements:

for entry in form.locations.entries:
    print entry.data['location_id']
    print entry.data['city']
37
Jaime Gómez