我正在尝试在Flask中构建一个非常基本的应用程序:一种可以接受用户输入的表单(我是Web开发的新手)。我最初能够启动并运行它,但是当我尝试修改HTML以使其包含Bootstrap时,单击提交按钮时出现Not a valid choice
错误。
主要应用:
from flask import Flask, render_template, flash, session, redirect, url_for, request
from forms import CustomAnalyticsMenu
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'
@app.route('/')
@app.route('/home')
def home():
return render_template('home.html')
@app.route('/custom_analytics_menu', methods=['GET', 'POST'])
def custom_analytics_menu():
form = CustomAnalyticsMenu()
if form.validate_on_submit():
print("validated_on_submit")
session['menu_item'] = form.menu_item.data
return redirect(url_for('submission'))
else:
print(form.errors)
return render_template('custom_analytics_menu.html', form=form)
@app.route('/submission', methods=['GET', 'POST'])
def submission():
return render_template('submission.html')
if __name__ == '__main__':
app.run(debug=True)
表格:
from flask_wtf import FlaskForm
from wtforms import StringField, RadioField, SelectField, SubmitField
from wtforms.validators import DataRequired
class CustomAnalyticsMenu(FlaskForm):
menu_item = SelectField('Menu Item:', choices=[('option_one', 'Option One'),
('option_two', 'Option Two'),
('option_three', 'Option Three')])
generate_deck = SubmitField('Generate deck')
HTML:
这是有效的HTML代码:
{% extends "layout.html" %}
{% block content %}
<div>
<form method="POST" action="">
{{ form.hidden_tag() }}
{{ form.menu_item.label }} {{ form.menu_item }}
{{ form.generate_deck() }}
</form>
</div>
{% endblock %}
但是,当我更改此部分时:
{{ form.menu_item.label }} {{ form.menu_item }}
对此:(我从这里得到:https://getbootstrap.com/docs/4.0/components/forms/#form-controls)
<div class="form-group">
<label for="menu_item">{{ form.menu_item.label }}</label>
<select class="form-control" id="menu_item">
{% for item in form.menu_item.choices %}
<option>{{ item[-1] }}</option>
{% endfor %}
</select>
</div>
我的SelectField
在功能上看起来相同(显然,它具有Bootstrap样式),但是现在当我单击Submit按钮时,什么也没有发生,并且出现错误Not a valid choice
。这是我要执行的操作的摘要,我也有一个RadioField
和一个StringField
,但是在尝试应用相似的样式时,也会遇到相同的错误。有人可以帮助我了解我要去哪里哪里吗?
答案 0 :(得分:0)
经过编辑,将name
字段中的<select>
属性包括在内,以解决其他问题,并在@RaghavPaliwal的答案中作了进一步说明。
您传递给choices
的{{1}}是a sequence of (value, label) pairs。
在您的示例中,这些是:
SelectField
这些元组的第一个元素是该选项表示的实际值,对于您的应用程序而言是有意义的。需要将其设置为[('option_one', 'Option One'),
('option_two', 'Option Two'),
('option_three', 'Option Three')]
标签的value
属性。每个元组中的第二个元素只是该选项表示要显示给用户的值的格式很好的表示形式。
因此,您需要为每个<option>
标签提供value
属性:
<option>
如果您没有为<div class="form-group">
<label for="menu_item">{{ form.menu_item.label }}</label>
<select class="form-control" id="menu_item" name="menu_item">
{% for val, text in form.menu_item.choices %}
<option value="{{ val }}">{{ text }}</option>
{% endfor %}
</select>
</div>
标签提供value
属性,那么标签的内容将作为表单字段的值传递。在您的情况下,这意味着如果选择<option>
,则字符串'Option One'
将作为字段的值传递。然后,表单验证会测试它是否包含在选项值'Option One'
,'option_one'
或'option_two'
中,所以验证失败。
答案 1 :(得分:0)
我想我明白了!我看到了另一个StackedOverflow问题(Why is my flask form validation returning Not a valid choice?),他们在var request = require("request");
request({uri: "https://www.canalmeio.com.br/ultima-edicao/"}, /*this is the URL where I pick up the text */
function(error, response, body) {
console.log(body);
});
});
var params = {
OutputFormat: mp3,
OutputS3BucketName: 'BUCKETNAMEXXXX'',
Text: console.log,
VoiceId: Cristiano,
Engine: standard,
LanguageCode: pt-BR,
OutputS3KeyPrefix: 'meio',
SampleRate: '22050',
TextType: text
};
polly.startSpeechSynthesisTask(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
中有一个name
字段。我更新了(值,标签)对,使它们匹配(即<select>
而不是('Option One', 'Option One')
),并将代码更新为:
('option_one', 'Option One')
成功了!或者,我可以保留(值,标签)对相同,并使用上面SuperShoot回答中的代码。我不能说我完全理解为什么需要<div class="form-group">
<label for="menu_item">{{ form.menu_item.label }}</label>
<select class="form-control" name="menu_item">
{% for item in form.menu_item.choices %}
<option>{{ item[-1] }}</option>
{% endfor %}
</select>
</div>
标签,所以如果有人对此有一个解释,我很想听听。