Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
371 views
in Technique[技术] by (71.8m points)

python - Add fields dynamically to WTForms form

I want to define a form class with fields based on a dict of name: label. I tried the following, which nearly worked. However, rendering the fields in a 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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Use setattr to add new fields as attributes of the form class. This will cause WTForms to set up the field correctly instead of 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 the attr filter.

{% for key, value in record.items() %}:
    {{ form|attr(key)() }}
{% endfor %}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...