【问题标题】:Why is my flask form validation returning Not a valid choice?为什么我的烧瓶表单验证返回不是一个有效的选择?
【发布时间】:2018-02-26 12:38:36
【问题描述】:

我一直试图弄清楚为什么我的 Flask 表单无法正确验证我的选择字段选项,即使这些选项来自选择字段选项。

我的假设是从服务器传回的 select 选项是 unicode 并且正在与作为字符串的选项进行比较,但是,我认为 coerce=str 可以解决这个问题。我打印出表单数据和请求数据,即下面的输出。为什么它不起作用?

我的代码附在下面,从输出字典中删除了 csrf 令牌键。这似乎是一件非常简单的事情,但我无法弄清楚。

forms.py

class PlatformForm(FlaskForm):
    platform_options = [('test', 'Test'), ('test2','Test2')]
    platforms = wtforms.SelectField('Platforms', choices=platform_options, coerce=str, validators=[DataRequired()])

views.py

@app.route('/', methods=['POST', 'GET'])
def index():
    form = forms.PlatformForm()
    if form.is_submitted():
        print form.data
        print request.form
    if form.errors:
        print form.errors
return render_template('home.html', form=form)

index.html

   {% extends "base.html" %}
   {% block content %}
   <h4>Select a Platform</h4>
   <form method="POST">
       {{ form.csrf_token }}
       <select class="custom-select" name="platform">
       {% for value, text in form.platforms.choices %}<br>
           <option value="{{ value }}">{{ text }}</option>
       {% endfor %}
       </select>
<button id="submit_inputs" type="submit" class="btn btn-default">Submit</button>
    </form>
    {% endblock %}

输出

   {'platforms': 'None'}
   ImmutableMultiDict([('platform', u'test')])
   {'platforms': [u'Not a valid choice']}

编辑: 我解决了这个问题。这是我通过 HTML 和 Jinja 创建 Select 下拉菜单的方式。当传递回 Python 时,遍历选项并创建选项标记似乎不会实例化表单数据本身中的任何内容。将整个 for 循环更改为

{{form.platforms}}

创建了一个实际有效的选择下拉字段。

【问题讨论】:

    标签: python html flask flask-wtforms


    【解决方案1】:

    你的名字不匹配。在表单中,您将选择字段命名为 platforms(复数)。在 HTML 中,您使用 platform(单数)。

    我建议您让 WTForms 为您生成 HTML,而不是手动呈现模板中的字段。对于表单标签,您可以使用{{ form.platforms.label }},对于实际字段,您可以使用{{ form.platforms() }}。您可以传递任何您想要字段作为关键字参数的属性。

    【讨论】:

    • 哈,多么好的时机,我刚刚添加了一个与此类似的编辑。我想知道为什么这么难弄清楚...你知道使用 jinja 实例化字段的文档在哪里吗?
    • 你是这个意思吗? flask-wtf.readthedocs.io/en/stable/…
    【解决方案2】:

    我认为由于您在 html 文件中呈现表单的方式,可能会出现问题。如果我的预感是正确的,试试这个:

    {% extends "base.html" %}
    {% block content %}
    <h4>Select a Platform</h4>
    <form method="POST">
        {{ form.hidden_tag() }}
        Select: {{ form.plaforms}}
        {{ form.submit(class="btn btn-default") }}
    </form>
    {% endblock %}
    

    然后在您的views.py 文件中尝试if form.validate_on_submit()

    取自this堆栈溢出答案pjcunningham:

    "validate_on_submit() 是 is_submitted() 和 validate() 的快捷方式。

    从源代码第 89 行,is_submitted() 如果表单返回 True 提交是一个活动请求,方法是 POST、PUT、PATCH 或 删除。

    一般来说,当路由可以同时接受 GET 和 POST 方法,而您只想在 POST 请求上进行验证。”

    【讨论】:

    • 感谢您的回答,但不确定问题是否被理解。验证和提交的方法似乎工作正常,问题是验证告诉我我的选项无效,即使它不是。 form.validate_on_submit() 只返回 False
    • 明白了。我编辑了我的答案,所以你也可以试试。
    猜你喜欢
    • 1970-01-01
    • 2013-01-14
    • 2020-11-18
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多