使用wtforms动态添加输入字段

27

我不太确定如何处理这个问题,希望我能找到解决方法。

例如,我在页面上有一个充满地址的表格。这些地址的数量是动态的(可能是5或10或任何其他数量)。我想在一个页面上编辑它们的可能性。

我的做法是创建一个带有wtforms的表单来编辑一个地址,并在jinja2的for循环中将其乘以并附加到html属性的nameid,从迭代中提取每一行数据,然后在需要评估时将其放回我的表单中。

所以这个例子的表单将是:

class AdressForm(Form):
    name = TextField()

现在,我的模板方法如下所示(拆分为一个输入字段):

{% for address in addresses %}
    {{ forms.render_field(addressform.name, id = "name_" ~ loop.index0, 
                          name = "name_" ~ loop.index0, value = address.name) }}
{% endfor %}

(forms.render_field仅仅是一个宏,用于指定wtforms的field函数所需的正确类,就像在许多教程中使用的那样)

因此这个不起作用了,因为你不能手动传递name参数给field函数,因为wtforms会根据初始表单的变量名创建name html参数。

那么,有没有办法向要呈现的表单名称添加前缀或后缀呢?还是我的方法完全错误了?

或者我必须自己全盘完成(我真的试图避免这种情况)

2个回答

48

WTForms有一个名为FormField的元字段和另一个名为FieldList的元字段。将这两者结合起来即可得到所需的结果:

class AddressEntryForm(FlaskForm):
    name = StringField()

class AddressesForm(FlaskForm):
    """A form for one or more addresses"""
    addresses = FieldList(FormField(AddressEntryForm), min_entries=1)

要在AddressesForm中创建条目,只需使用字典的列表:

user_addresses = [{"name": "First Address"},
                  {"name": "Second Address"}]
form = AddressesForm(addresses=user_addresses)
return render_template("edit.html", form=form)

然后,在您的模板中,只需循环处理子表单:

{% from 'your_form_template.jinja' import forms %}
{% for address_entry_form in form.addresses %}
    {{ address_entry_form.hidden_tag() }}
    {# Flask-WTF needs `hidden_tag()` so CSRF works for each form #}
    {{ forms.render_field(address_entry_form.name) }}
{% endfor %}

WTForms会自动正确地为名称和ID添加前缀,因此当您将数据提交回来时,您只需获取form.addresses.data,就可以得到一个包含更新数据的字典列表。


有没有办法使其适应模板,以便我可以通过模板添加字段?我想允许用户单击“+”按钮并将另一个字段添加到FieldList中。 - Kurt Price
是的 - 只需将点击后的请求发送到您的端点,当接收到该特定的POST请求时,只需向数据列表(在上面的示例中为user_addresses)添加另一个条目即可。 - Sean Vieira
2
@alexfvolk 你的问题在其他地方得到了回答吗? - Nilesh
2
要使用CSRF令牌,请确保将“hidden_tag()”添加到两个表单中。因此,在此示例中,需要{{form.hidden_tag()}}{{address_entry_form.hidden_tag()}} - Gman
3
请注意,“Form”已被弃用(请使用“FlaskForm”)。我认为“render_field”方法不再起作用,请直接调用“address_entry_form.name”。 - Tyler Dane Hitzeman
显示剩余4条评论

6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,