10

ユーザー入力に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)
4

2 に答える 2

11

Flaskはrequest.formをwerkzeugMultiDictオブジェクトとして返します。これは辞書のようなものですが、不注意な人のための罠があります。

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

MultiDictは、すべての標準辞書メソッドを実装します。内部的には、キーのすべての値をリストとして保存しますが、標準のdictアクセスメソッドはキーの最初の値のみを返します。他の値にもアクセスしたい場合は、listメソッドを使用する必要があります。

ただし、もっと簡単な方法があると思います。お願いして、交換してみてください。

language =  request.form['language']

language =  form.language.data

それが違うかどうか見てみませんか?WTFormsはMultiDictオブジェクトを処理し、フォームデータをバインドしたのでリストを返す必要があります。

于 2012-11-26T06:01:49.603 に答える
3

私は最近この問題に遭遇しました。を使用して選択したすべてのアイテムを取得できることがわかりました

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

これは、選択されたすべてのアイテムを含むリストに評価されます。あなたの場合、以下を使用してください:

languages = request.form.getlist('language')
于 2020-10-18T22:11:51.657 に答える