Flask / Python / WTForms 验证和动态设置 SelectField 选择
Flask / Python / WTForms validation and dynamically set SelectField choices
我正在尝试创建一个简单的 Flask
/ Python
单页 Web 应用程序,该应用程序使用为 SelectField 动态创建的选项。
但是,我无法使用动态创建的选项将其设置为 POST,而且还有一些有趣的验证行为(将在代码后解释)
我在这里创建了一个最小失败示例:
from flask import Flask, render_template, flash, redirect
from flask_wtf import Form
from wtforms import IntegerField, SubmitField, SelectField
from wtforms.validators import DataRequired, NumberRange, Optional
# Set up app and config
DEBUG = True
SECRET_KEY = '42721564'
app = Flask(__name__)
app.config.from_object(__name__)
# Main stuff starts here
class SelectFieldForm(Form):
default_field = SelectField('Default Set SelectField', choices=[(i, i) for i in range(0,60,5)], coerce=int)
default_field_2 = SelectField('Default Set SelectField', choices=[(i, i) for i in range(0,60,5)], coerce=int)
dynamic_field = SelectField('Dynamically Set Selectfield', choices=[], validators=[Optional()], coerce=int)
get_default_field_value_difference = SubmitField(label='Get Default Field Difference')
deduct_dynamic_field_value = SubmitField(label='Deduct Dynamic Field Value')
@app.route('/mfe-dynamic-selectfield', methods=['GET', 'POST'])
def failingSelectField():
form = SelectFieldForm()
if form.validate_on_submit():
print("validated")
difference = form.default_field_2.data - form.default_field.data
if form.get_default_field_value_difference.data:
flash( difference )
form.dynamic_field.choices = [(i,i) for i in range(0,difference,5)]
return render_template('mfe-dynamic-selectfield.html', form=form)
if form.deduct_dynamic_field_value.data:
if form.dynamic_field.data:
deducted = difference - form.dynamic_field.data
flash( deducted )
else:
flash( "no dynamic field value chosen")
return render_template('mfe-dynamic-selectfield.html', form=form)
else:
flash( "nope" )
return render_template('mfe-dynamic-selectfield.html', form=form)
if __name__ == '__main__':
app.run()
打开页面工作正常,并立即闪烁 "nope",正如预期的那样。
正在计算默认设置字段之间的差异:
- 每次都工作,只要它们都设置为“0”
-如果任一字段未设置为“0”,则每隔一个 POST 验证失败,时间正确计算差异并动态设置最后一个字段。
尝试 POST 使用动态设置的字段每次都失败。
我是不是漏掉了一些很明显的东西?
我正在使用这个进行渲染:
{% block content %}
<form action="" method="post" name="mfe-dynamic-selectfield">
{{ form.hidden_tag() }}
<table>
<tr>
<td> Calculated value </td>
<td>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</td>
</tr>
<br>
<tr>
<td>Default SelectField 1</td>
<td>Default SelectField 2</td>
<td>Dynamic Selectfield</td>
</tr>
<br>
<tr>
<td>{{ form.default_field }}</td>
<td>{{ form.default_field_2 }}</td>
<td>{{ form.dynamic_field }}</td>
</tr>
<tr>
<td>{{ form.get_default_field_value_difference }}</td>
<td>{{ form.deduct_dynamic_field_value }}</td>
</tr>
</table>
</form>
{% endblock %}
它每隔一段时间就会失败,因为 form.dynamic_field
的值在 0
和 None
之间波动。仅当值为 None
.
时表单通过验证
这是因为 form.dynamic_field.choices
在验证时是 []
(空列表)。因此,那里出现的任何价值都会被拒绝。您可能希望在尝试验证之前动态设置选项;也许是这样的:
@app.route('/mfe-dynamic-selectfield', methods=['GET', 'POST'])
def failingSelectField():
form = SelectFieldForm()
# Calculate dynamic field choices
try:
difference = form.default_field_2.data - form.default_field.data
form.dynamic_field.choices = [(i,i) for i in range(0,difference,5)]
except TypeError:
pass
if form.validate_on_submit():
# (continue as usual)
现在表单将按预期进行验证。
当然,您可能应该在前面添加一些代码以确保 default_field
确实具有有效的选择值(不仅仅是任意两个整数)。另一种选择是将 dynamic_field
放在第二种形式中。然后您可以验证第一个表单,并使用它的值来计算第二个表单的有效选择。
我正在尝试创建一个简单的 Flask
/ Python
单页 Web 应用程序,该应用程序使用为 SelectField 动态创建的选项。
但是,我无法使用动态创建的选项将其设置为 POST,而且还有一些有趣的验证行为(将在代码后解释)
我在这里创建了一个最小失败示例:
from flask import Flask, render_template, flash, redirect
from flask_wtf import Form
from wtforms import IntegerField, SubmitField, SelectField
from wtforms.validators import DataRequired, NumberRange, Optional
# Set up app and config
DEBUG = True
SECRET_KEY = '42721564'
app = Flask(__name__)
app.config.from_object(__name__)
# Main stuff starts here
class SelectFieldForm(Form):
default_field = SelectField('Default Set SelectField', choices=[(i, i) for i in range(0,60,5)], coerce=int)
default_field_2 = SelectField('Default Set SelectField', choices=[(i, i) for i in range(0,60,5)], coerce=int)
dynamic_field = SelectField('Dynamically Set Selectfield', choices=[], validators=[Optional()], coerce=int)
get_default_field_value_difference = SubmitField(label='Get Default Field Difference')
deduct_dynamic_field_value = SubmitField(label='Deduct Dynamic Field Value')
@app.route('/mfe-dynamic-selectfield', methods=['GET', 'POST'])
def failingSelectField():
form = SelectFieldForm()
if form.validate_on_submit():
print("validated")
difference = form.default_field_2.data - form.default_field.data
if form.get_default_field_value_difference.data:
flash( difference )
form.dynamic_field.choices = [(i,i) for i in range(0,difference,5)]
return render_template('mfe-dynamic-selectfield.html', form=form)
if form.deduct_dynamic_field_value.data:
if form.dynamic_field.data:
deducted = difference - form.dynamic_field.data
flash( deducted )
else:
flash( "no dynamic field value chosen")
return render_template('mfe-dynamic-selectfield.html', form=form)
else:
flash( "nope" )
return render_template('mfe-dynamic-selectfield.html', form=form)
if __name__ == '__main__':
app.run()
打开页面工作正常,并立即闪烁 "nope",正如预期的那样。
正在计算默认设置字段之间的差异: - 每次都工作,只要它们都设置为“0” -如果任一字段未设置为“0”,则每隔一个 POST 验证失败,时间正确计算差异并动态设置最后一个字段。
尝试 POST 使用动态设置的字段每次都失败。
我是不是漏掉了一些很明显的东西?
我正在使用这个进行渲染:
{% block content %}
<form action="" method="post" name="mfe-dynamic-selectfield">
{{ form.hidden_tag() }}
<table>
<tr>
<td> Calculated value </td>
<td>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</td>
</tr>
<br>
<tr>
<td>Default SelectField 1</td>
<td>Default SelectField 2</td>
<td>Dynamic Selectfield</td>
</tr>
<br>
<tr>
<td>{{ form.default_field }}</td>
<td>{{ form.default_field_2 }}</td>
<td>{{ form.dynamic_field }}</td>
</tr>
<tr>
<td>{{ form.get_default_field_value_difference }}</td>
<td>{{ form.deduct_dynamic_field_value }}</td>
</tr>
</table>
</form>
{% endblock %}
它每隔一段时间就会失败,因为 form.dynamic_field
的值在 0
和 None
之间波动。仅当值为 None
.
这是因为 form.dynamic_field.choices
在验证时是 []
(空列表)。因此,那里出现的任何价值都会被拒绝。您可能希望在尝试验证之前动态设置选项;也许是这样的:
@app.route('/mfe-dynamic-selectfield', methods=['GET', 'POST'])
def failingSelectField():
form = SelectFieldForm()
# Calculate dynamic field choices
try:
difference = form.default_field_2.data - form.default_field.data
form.dynamic_field.choices = [(i,i) for i in range(0,difference,5)]
except TypeError:
pass
if form.validate_on_submit():
# (continue as usual)
现在表单将按预期进行验证。
当然,您可能应该在前面添加一些代码以确保 default_field
确实具有有效的选择值(不仅仅是任意两个整数)。另一种选择是将 dynamic_field
放在第二种形式中。然后您可以验证第一个表单,并使用它的值来计算第二个表单的有效选择。