Dynamically add fields to WTForms
I want to define a form class with dict based fields name: label
. I tried the following which almost worked. However, rendering the fields in the template gave AttributeError: 'UnboundField' object has no attribute '__call__'
. How can I dynamically add fields to a form?
def build_form(name, record):
class ContactForm(FlaskForm):
name = StringField(name)
fieldlist = {}
for key, value in record.items():
fieldlist[key] = StringField(key)
@app.route('/', methods=['GET', 'POST'])
def showform():
form = ContactForm(request.form)
if request.method == 'POST':
return 'form processed'
return render_template('cardcompare.tpl', record=record, form=form)
<form method=post>
{{ form.name() }}
{% for key, value in record.items() %}
{{ form.fieldlist[key]() }}
{% endfor %}
<input type=submit value=Register>
</form>
+3
source to share
1 answer
Use setattr
to add new fields as attributes of the form class. This will cause WTForms to set up the field correctly rather than keeping the unbound field.
# form class with static fields
class MyForm(FlaskForm):
name = StringField('static field')
record = {'field1': 'label1', 'field2': 'label2'}
# add dynamic fields
for key, value in record.items():
setattr(MyForm, key, StringField(value))
In the template, you can iterate over the fields using a filter attr
.
{% for key, value in record.items() %}:
{{ form|attr(key)() }}
{% endfor %}
+2
source to share