为什么我的 Flask 表单验证返回 Not a valid choice?
Why is my flask form validation returning Not a valid choice?
我一直在努力弄清楚为什么我的 Flask 表单无法正确验证我的 select 字段选择,即使这些选择来自 select 字段选项。
我的假设是从服务器传回的 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}}
创建了一个实际有效的 select 下拉字段。
我认为您在 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()
取自 stack overflow answer by pjcunningham:
"validate_on_submit() is a shortcut for is_submitted() and validate().
From the source code, line 89, is_submitted() returns True if the form
submitted is an active request and the method is POST, PUT, PATCH, or
DELETE.
Generally speaking, it is used when a route can accept both GET and
POST methods and you want to validate only on a POST request."
您的名字不匹配。在表单中,您将 select 字段命名为 platforms
(复数)。在 HTML 中,您使用 platform
(单数)。
我建议您让 WTForms 为您生成 HTML,而不是手动呈现模板中的字段。对于表单标签,您可以使用 {{ form.platforms.label }}
,对于实际字段,您可以使用 {{ form.platforms() }}
。您可以传递任何您希望字段具有的属性作为关键字参数。
我一直在努力弄清楚为什么我的 Flask 表单无法正确验证我的 select 字段选择,即使这些选择来自 select 字段选项。
我的假设是从服务器传回的 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}}
创建了一个实际有效的 select 下拉字段。
我认为您在 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()
取自
"validate_on_submit() is a shortcut for is_submitted() and validate().
From the source code, line 89, is_submitted() returns True if the form submitted is an active request and the method is POST, PUT, PATCH, or DELETE.
Generally speaking, it is used when a route can accept both GET and POST methods and you want to validate only on a POST request."
您的名字不匹配。在表单中,您将 select 字段命名为 platforms
(复数)。在 HTML 中,您使用 platform
(单数)。
我建议您让 WTForms 为您生成 HTML,而不是手动呈现模板中的字段。对于表单标签,您可以使用 {{ form.platforms.label }}
,对于实际字段,您可以使用 {{ form.platforms() }}
。您可以传递任何您希望字段具有的属性作为关键字参数。