简体   繁体   English

Flask 应用程序使用 WTForms 和 SelectMultipleField

[英]Flask App Using WTForms with SelectMultipleField

I have a Flask application that uses WTForms for user input.我有一个使用 WTForms 进行用户输入的 Flask 应用程序。 It uses a SelectMultipleField in a form.它在表单中使用SelectMultipleField I can't seem to get the app to POST all items in the field when selected;我似乎无法让应用程序在选择时发布该字段中的所有项目; it only sends the first item selected regardless of how many the user selects.它只发送第一个选择的项目,而不管用户选择了多少。

The Flask documentation says this about the data sent from this field type, but I don't see this behavior: Flask 文档说明了从该字段类型发送的数据,但我没有看到这种行为:

The data on the SelectMultipleField is stored as a list of objects, each of which is checked and coerced from the form input. SelectMultipleField 上的数据存储为对象列表,每个对象都从表单输入中进行检查和强制转换。

Here's a complete, minimal Flask app that illustrates this:这是一个完整的、最小的 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)

Flask returns request.form as a werkzeug MultiDict object. Flask 将 request.form 作为 werkzeug MultiDict 对象返回。 This is kind of like a dictionary, only with traps for the unwary.这有点像一本字典,只是为粗心的人设置了陷阱。

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

MultiDict implements all standard dictionary methods. MultiDict 实现了所有标准的字典方法。 Internally, it saves all values for a key as a list, but the standard dict access methods will only return the first value for a key. 在内部,它将一个键的所有值保存为一个列表,但标准的字典访问方法将只返回一个键的第一个值。 If you want to gain access to the other values, too, you have to use the list methods. 如果您也想访问其他值,则必须使用列表方法。

However, I think there's an easier way.但是,我认为有一种更简单的方法。 Can you do me a favor and try replacing:你能帮我一个忙,尝试更换:

language =  request.form['language']

with

language =  form.language.data

and see if that's any different?看看有什么不同吗? WTForms should handle the MultiDict object and just return a list for you since you've bound form data to it. WTForms 应该处理 MultiDict 对象并只为您返回一个列表,因为您已经将表单数据绑定到它。

I ran into this problem recently.我最近遇到了这个问题。 I found that you can retrieve all the items selected using我发现你可以检索所有选择的项目

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

This evaluates to a list with all selected items in it.这将计算为一个列表,其中包含所有选定的项目。 In your case, use:在你的情况下,使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM