如何使用FormFields的WTForms FieldList?

kra*_*r65 16 python forms fieldlist flask wtforms

我正在使用Flask建立一个网站,我在其中使用WTForms.在表单中,我现在想要使用FormFields的FieldList,如下所示:

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

class CompanyForm(Form):
    company_name = StringField('company_name')
    locations = FieldList(FormField(LocationForm))
Run Code Online (Sandbox Code Playgroud)

所以让人们有能力进入一个有两个地点的公司(动态添加地点的时间比较晚)我在前面这样做:

<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>
Run Code Online (Sandbox Code Playgroud)

所以在提交时我打印的位置:

print companyForm.locations.data
Run Code Online (Sandbox Code Playgroud)

但我明白了

[{'location_id': u'', 'city': u''}]
Run Code Online (Sandbox Code Playgroud)

我可以使用locationForm打印第一个位置的值(见下文),但我仍然不知道如何获取第二个位置的数据.

print locationForm.location_id.data
print locationForm.city.data
Run Code Online (Sandbox Code Playgroud)

所以位置列表确实有一个带空值的dict,但是:

  1. 为什么地点列表只有一个,而不是两个?
  2. 为什么位置中的值是空的?

有谁知道我在这里做错了什么?欢迎所有提示!

Jai*_*mez 37

对于初学者来说,还有一个供一个参数FieldList中被称为min_entries,这将使空间为您的数据:

class CompanyForm(Form):
    company_name = StringField('company_name')
    locations = FieldList(FormField(LocationForm), min_entries=2)
Run Code Online (Sandbox Code Playgroud)

这将按您需要的方式设置列表.接下来,您应该直接从locations属性中呈现字段,以便正确生成名称:

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

看看渲染的html,输入应该有这样的名字locations-0-city,这样WTForms会知道哪个是哪个.

或者,对于元素的自定义渲染

{% for l in companyForms.locations %}
{{ l.form.city }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

(仅在wtforms中l.city是简写l.form.city.但是,该语法似乎与Jinja冲突,并且有必要l.form.city在模板中使用explicit .)

现在准备好提交的数据,只需创建CompanyForm并迭代这些位置:

for entry in form.locations.entries:
    print entry.data['location_id']
    print entry.data['city']
Run Code Online (Sandbox Code Playgroud)

  • 好吧...如果您需要控制体验,总会有一点您必须手动接管,在这种情况下,您唯一真正需要的是输入具有正确名称的内容,所以继续这样做,只要因为你有一个`&lt;input name=locations-0-city&gt;` 事情会解决的:) (2认同)