WTForm Flask из списка меток полей

#flask #dynamic #jinja2 #flask-wtforms #wtforms

#flask #динамический #jinja2 #колба-wtforms #wtforms

Вопрос:

Я пытаюсь создать динамическую форму из заданного списка меток, используя Flask, WTForms и Jinja2. Форма должна содержать a StringField для каждой заданной метки. Мой текущий подход заключается в использовании FieldList like в приведенном ниже коде.

Моя проблема с этим подходом заключается в том, что я не могу различать ключи в словаре каждого запроса.

request.form дает мне это ImmutableMultiDict([('text', ''), ('text', ''), ('submit', 'submit')]) с дубликатами ключей.

Как я могу узнать, какое значение было введено в какое StringField ?

В идеале request.form должно выглядеть так ImmutableMultiDict([('field 1', ''), ('field 2', ''), ('submit', 'submit')]) .

Интерфейс (index.html )

 <!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <form action="" method="post">
            {% for entry in form.entries %}
                <p>{{entry.text.label}}: {{ entry.text }}</p> 
            {% endfor %}
            <p>{{form.submit()}}</p>
        </form>
    </body>
</html>
 

Серверная часть

 from wtforms import FieldList, FormField, StringField, SubmitField
from flask_wtf import FlaskForm


class TextForm(FlaskForm):
    text = StringField('Placeholder')

class TextListForm(FlaskForm):
    entries = FieldList(FormField(TextForm))
    submit = SubmitField(u'submit')


from flask import Flask, render_template, request

app = Flask(__name__)
app.config.update(
    SECRET_KEY = 'asdf',
)
field_names = ["field 1", "field 2"]


@app.route('/', methods=['POST', 'GET'])
def index():
    fields = []
    for name in field_names:
        text_entry = TextForm()
        text_entry.text.label = name
        fields.append(text_entry)

    form = TextListForm()
    form.entries = fields

    if form.is_submitted():
        print(request.form)

    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)
 

Вывод: ImmutableMultiDict([('text', ''), ('text', ''), ('submit', 'submit')])

Ответ №1:

Я просто забыл указать имя поля: text_entry.text.name = name

 @app.route('/', methods=['POST', 'GET'])
def index():
    fields = []
    for name in field_names:
        text_entry = TextForm()
        text_entry.text.label = name
        text_entry.text.name = name
        fields.append(text_entry)

    form = TextListForm()
    form.entries = fields

    if form.is_submitted():
        print(request.form)

    return render_template('index.html', form=form)
 

Теперь возвращается желаемый dict: ImmutableMultiDict([('field 1', ''), ('field 2', ''), ('submit', 'submit')])