我一直试图找出为什么我的Flask表单无法正确验证我的选择字段选项,即使这些选项来自select字段选项。
我的假设是从服务器传回的select选项是unicode,并且正在与字符串的选择进行比较,但是,我认为coerce = str会解决这个问题。我打印出表单数据并请求下面输出的数据。为什么它不起作用?
我的代码附在下面,从输出dict中删除了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}}
创建了一个实际可行的选择下拉字段。
答案 0 :(得分:1)
您的姓名不匹配。在表单中,您将选择字段命名为platforms
(复数)。在HTML中,您使用platform
(单数)。
我建议您不要手动渲染模板中的字段,而是让WTForms为您生成HTML。对于表单标签,您可以使用{{ form.platforms.label }}
,也可以使用实际字段{{ form.platforms() }}
。您可以将要添加的任何属性作为关键字参数传递。
答案 1 :(得分:0)
我认为由于您在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 %}
然后在if form.validate_on_submit()
文件
views.py
取自this
的pjcunningham:堆栈溢出答案&#34; validate_on_submit()是is_submitted()和validate()的快捷方式。
从源代码第89行开始,is_submitted()返回True表格 提交是一个活动请求,方法是POST,PUT,PATCH或 DELETE
一般来说,当路线可以接受GET和GET时使用它 POST方法,您只想在POST请求上进行验证。&#34;