"Not a valid choice" 仅在添加 Bootstrap 后才在 SelectField 中
"Not a valid choice" in SelectField Only After Adding Bootstrap
我正在尝试在 Flask 中构建一个非常基本的应用程序:一个接受用户一些输入的单一表单(我是网络开发的新手)。我最初能够启动它并 运行,但是当我尝试修改 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 样式),但是现在当我点击提交按钮时,没有任何反应,我得到错误 Not a valid choice
.这是我正在尝试做的事情的一个片段,我也有一个 RadioField
和一个 StringField
但是我在尝试应用类似的样式时也遇到了同样的错误。有人可以帮助我了解我哪里出错了吗?
编辑以在 <select>
字段上包含 name
属性作为附加问题的解决方案,并在 @RaghavPaliwal 的回答中进一步解释。
您传递给 SelectField
的 choices
是 a sequence of (value, label) pairs。
在您的示例中,这些是:
[('option_one', 'Option One'),
('option_two', 'Option Two'),
('option_three', 'Option Three')]
这些元组的第一个元素是选项代表的实际值,并且对您的应用程序有意义。它需要设置为 <option>
标签的 value
属性。每个元组中的第二个元素只是一个格式良好的表示形式,表示选项代表显示给用户的值。
因此,您需要为每个 <option>
标签提供一个 value
属性:
<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>
如果您不为 <option>
标签提供 value
属性,标签的内容将作为表单字段的值传递。在您的情况下,这意味着如果选择了 'Option One'
,则字符串 'Option One'
将作为字段的值传递。然后表单验证测试它是否包含在选项值之一 'option_one'
、'option_two'
或 'option_three'
中,因此验证失败。
我想我明白了!我看到了另一个 StackedOverflow 问题 (),他们的 <select>
中有一个 name
字段。我更新了我的 (value, label) 对,使它们匹配(即 ('Option One', 'Option One')
而不是 ('option_one', 'Option One')
)并将代码更新为:
<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>
成功了!或者,我可以让 (value, label) 对保持不变,并使用上面 SuperShoot 的答案中的代码。我不能说我完全理解 为什么 需要 name
标签,所以如果有人对此有解释,我很想听听。
我正在尝试在 Flask 中构建一个非常基本的应用程序:一个接受用户一些输入的单一表单(我是网络开发的新手)。我最初能够启动它并 运行,但是当我尝试修改 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 样式),但是现在当我点击提交按钮时,没有任何反应,我得到错误 Not a valid choice
.这是我正在尝试做的事情的一个片段,我也有一个 RadioField
和一个 StringField
但是我在尝试应用类似的样式时也遇到了同样的错误。有人可以帮助我了解我哪里出错了吗?
编辑以在 <select>
字段上包含 name
属性作为附加问题的解决方案,并在 @RaghavPaliwal 的回答中进一步解释。
您传递给 SelectField
的 choices
是 a sequence of (value, label) pairs。
在您的示例中,这些是:
[('option_one', 'Option One'),
('option_two', 'Option Two'),
('option_three', 'Option Three')]
这些元组的第一个元素是选项代表的实际值,并且对您的应用程序有意义。它需要设置为 <option>
标签的 value
属性。每个元组中的第二个元素只是一个格式良好的表示形式,表示选项代表显示给用户的值。
因此,您需要为每个 <option>
标签提供一个 value
属性:
<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>
如果您不为 <option>
标签提供 value
属性,标签的内容将作为表单字段的值传递。在您的情况下,这意味着如果选择了 'Option One'
,则字符串 'Option One'
将作为字段的值传递。然后表单验证测试它是否包含在选项值之一 'option_one'
、'option_two'
或 'option_three'
中,因此验证失败。
我想我明白了!我看到了另一个 StackedOverflow 问题 (<select>
中有一个 name
字段。我更新了我的 (value, label) 对,使它们匹配(即 ('Option One', 'Option One')
而不是 ('option_one', 'Option One')
)并将代码更新为:
<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>
成功了!或者,我可以让 (value, label) 对保持不变,并使用上面 SuperShoot 的答案中的代码。我不能说我完全理解 为什么 需要 name
标签,所以如果有人对此有解释,我很想听听。