使用WTForms的Flask应用程序与SelectMultipleField

13

我有一个使用WTForms处理用户输入的Flask应用程序,其中包含一个SelectMultipleField的表单。但是,无论用户选择了多少项目,我似乎都无法让应用程序将该字段中的所有项POST出去;它只会发送第一个选择的项。

Flask文档对这个字段类型发送的数据有如下解释,但我没有看到这种行为:

SelectMultipleField中的数据作为对象列表存储,每个对象都会从表单输入中进行检查和强制转换。

以下是一个完整而简洁的Flask应用程序,可以说明这一点:

#!/usr/bin/env python

from flask import Flask, render_template_string, request
from wtforms import Form, SelectMultipleField

application = app = Flask('wsgi')

class LanguageForm(Form):
    language = SelectMultipleField(u'Programming Language', choices=[('cpp', 'C++'), ('py', 'Python'), ('text', 'Plain Text')])

template_form = """
{% block content %}
<h1>Set Language</h1>

<form method="POST" action="/">
    <div>{{ form.language.label }} {{ form.language(rows=3, multiple=True) }}</div>
    <button type="submit" class="btn">Submit</button>    
</form>
{% endblock %}

"""

completed_template = """
{% block content %}
<h1>Language Selected</h1>

<div>{{ language }}</div>

{% endblock %}

"""

@app.route('/', methods=['GET', 'POST'])
def index():
    form = LanguageForm(request.form)

    if request.method == 'POST' and form.validate():
        print "POST request and form is valid"
        language =  request.form['language']
        print "languages in wsgi.py: %s" % request.form['language']
        return render_template_string(completed_template, language=language)

    else:

        return render_template_string(template_form, form=form)

if __name__ == '__main__':
    app.run(debug=True)
2个回答

13

Flask将request.form返回为werkzeug MultiDict对象。这有点像字典,只不过对于不谨慎的人来说可能会有陷阱。

http://flask.pocoo.org/docs/api/#flask.request http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.MultiDict

MultiDict实现了所有标准字典方法。在内部,它将一个键的所有值保存为列表,但是标准字典访问方法只会返回该键的第一个值。如果您想获得其他值,您必须使用列表方法。

然而,我认为有一种更简单的方法。 你能帮我试着替换一下:

language =  request.form['language']

带有

language =  form.language.data

那你试试看有什么不同呢?WTForms 应该可以处理 MultiDict 对象,并为你返回一个列表,因为你已经将表单数据绑定到它上面了。


谢谢。为了完整起见:form.data将提供所有表单字段的数据。用于创建模型类的新实例非常有用。 - Alvaro Rodriguez Scelza

4

我最近遇到了这个问题。我发现你可以使用以下方法检索所有选定的项:

request.form.getlist('...')

这将返回一个包含所有选中项的列表。在您的情况下,请使用:

languages = request.form.getlist('language')

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