Flask针对SelectField的WTForm验证失败...为什么?
问题描述:
我正在使用Flask和WTForm来制作一个网络应用程序,到目前为止我的其他两个字段验证正常,但SelectField抛出错误'请选择一个宠物'。正如我自己指定的那样,即它认为它没有收到有效的输入。 SelectField.choices匹配到呈现为HTML的选项,所以我做错了什么?Flask针对SelectField的WTForm验证失败...为什么?
app.py
from flask_wtf import Form
from flask_wtf.csrf import CSRFProtect
from wtforms import IntegerField, StringField, SelectField, validators,
ValidationError
from flask import Flask, request, flash, render_template
app = Flask(__name__)
app.secret_key = 'xxxxxxxxxxxx'
csrf = CSRFProtect(app)
pChoices = [('-1', '-----'),
('0', 'Cat'),
('1', 'Dog'),
('2', 'Parrot'),
('3', 'Hamster')]
class paymentForm(Form):
productF = SelectField('productF', [validators.input_required("Please choose a pet.")], choices=[pChoices], coerce=int)
buyer_id = StringField('buyer', [validators.input_required("Please enter your name.")])
paid = DecimalField('paid', [validators.input_required("please enter payment amount")])
@app.route('/', methods=['POST', 'GET'])
def index():
form = paymentForm(request.form, csrf_enabled=True)
if form.validate_on_submit():
flash('Order Placed Successfully', 'success')
data = form.data
record_order(data)
print(data['price'])
return render_template('confirmation.jinja',
pets=PETS,
title='Confirmation Page',
form=form, error=form.errors,
** context)
elif not form.validate_on_submit:
flash('Submission error, please check the form', 'success')
return render_template('index.jinja',
title='Order Form',
form=form,
error=form.errors,
**context)
if __name__ == '__main__':
app.run(debug=True, use_reloader=True)
index.jinja
{% extends 'base.jinja' %}
{% block main %}
<form method="post">
<div class="form-group row">
<label for="product" class="col-sm-2 form-control-label">Pet:</label>
<div class="col-sm-8">
<select id="productF" class="form-control" name="pet" onchange="Update()">
<option value="-1">-----</option>
{% for pet in pets %}
<option value="{{ loop.index -1 }}">{{ pet.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group row">
<label for="buyer" class="col-sm-2 form-control-label">Buyer:</label>
{% for message in form.buyer_id.errors %}
<div>{{ message }}</div>
{% endfor %}
<div class="col-sm-10">
<input type="text" class="form-control" id="buyer_id" name="buyer_id" placeholder="Buyer" value="{{ buyer_id }}" required>
</div>
</div>
<div class="form-group row">
<label for="paid" class="col-sm-2 form-control-label">Amount Paid:</label>
{% for message in form.paid.errors %}
<div>{{ message }}</div>
{% endfor %}
<div class="col-sm-10">
<input type="text" class="form-control" id="paid" name="paid" placeholder="Amount Paid" value="{{ paid }}" required>
</div>
</div>
{% if form.errors %}
{{ form.errors }}
{% endif %}
<div class="form-group row">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Place Order</button>
</div>
</div>
<input type="hidden" name="csrf_token" value="{{ csrf_token()
}}"/>
</form>
{% endblock %}
编辑我在神社文件,productF更新的代码字段的名字,我仍然收到错误。 Pets
对象作为JSON对象而不是app.py加载到HTML页面中,但据我所知,这些值是相同的;这是怎样的选择元素来自检查者出现:
<select id="product" class="form-control" name="product">
<option value="-1">-----</option>
<option value="0">Cat</option>
<option value="1">Dog</option>
<option value="2">Parrot</option>
<option value="3">Hamster</option>
</select>
答
你定义pChoices
为列表
pChoices = [('-1', '-----'),
('0', 'Cat'),
('1', 'Dog'),
('2', 'Parrot'),
('3', 'Hamster')]
但随后在SelectField
定义它包裹在另一个列表:
productF = SelectField(..., choices=[pChoices], ...)
使用choices=pChoices
应该修复它。
编辑:你也有pet
在表单模板神社字段名,你可能想使用productF
。
编辑2:在定义pChoices
的值和字段强制的方式中存在不匹配。从表单字段中删除coerce=int
,或者将pChoices
中的元组的第一个值设置为整数,而不是字符串。
将它改为'choices = pChoices'后仍然抛出同样的错误 –
请参阅编辑答案:) –
仍然没有运气,请参阅我编辑的问题 –