Flask - 无法在子表单中使用验证器
Flask - Unable use validators in SubForms
我的观点如下:
我有一个带有 FloatFields 的 FieldList 输入。
但是那些嵌套字段中的验证器没有 运行.
当我有一个基本表格时,NumberRange
工作正常。
但是当我有一个嵌套表单时,wtforms.validators.NumberRange
会触发以下错误:
TypeError: '<' not supported between instances of 'FloatField' and
'int'
我不知道为什么会出现该错误?
这是我的主要文件:
from flask import Flask, render_template, flash
from flask_wtf import FlaskForm
from wtforms import FloatField, SubmitField, StringField, FieldList, FormField
from wtforms.validators import NumberRange
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
class mySubForm(FlaskForm):
class Meta:
csrf = False
mySubField = FloatField(validators=[NumberRange(min=-100, max=100)])
class myForm(FlaskForm):
myField = FieldList(FormField(mySubForm))
mySubmit = SubmitField("Save")
@app.route('/', methods=['GET','POST'])
def home():
form = myForm()
xLabels = ["A", "B", "C", "D"]
for x in xLabels:
subForm = mySubForm()
form.myField.append_entry(subForm)
if form.validate_on_submit():
flash("success")
return render_template("draft.html", form=form)
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5000" ,debug=True)
这是我的模板:
<!DOCTYPE html>
<html>
<head>
<style>
.error{border-color: red;}
</style>
</head>
<body>
<div>
<form method="POST" action="/">
{{ form.hidden_tag() }}
{% for field in form.myField %}
{% if field.mySubField.errors %}
{{ field.mySubField(class="error") }}
{% for error in field.mySubField.errors %}
<span>{{ error }}</span>
{% endfor %}
{% else %}
{{ field.mySubField.data }}
{% endif %}
{% endfor %}
{{ form.mySubmit() }}
</form>
{% with messages = get_flashed_messages(with_categories=False) %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</body>
</html>
问题是 append_entry
不接受字段,它接受原始数据,因此验证失败,因为它将数字与 FloatField
进行比较。
向其传递一个字段也是您必须在模板中使用 mySubField.data
而不是简单地 mySubField()
的原因,因为实际上 mySubField
正在呈现另一个字段, 你通过的那个。
要修复它,您可以执行以下操作
form.myField.append_entry({'mySubField': some_number})
如上所述,您也可以修复模板:
{% else %}
{{ field.mySubField() }}
{% endif %}
顺便说一句,您可能希望将 add_entry
逻辑包含在条件中,这样它只发生在 GET
请求中,否则每次提交表单时都会添加新条目.
感谢 Luis,这是工作代码:
我的主文件:
from flask import Flask, render_template, flash, request
from flask_wtf import FlaskForm
from wtforms import FloatField, SubmitField, StringField, FieldList, FormField
from wtforms.validators import NumberRange
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
class myForm(FlaskForm):
myField = FieldList(FloatField(validators=[NumberRange(min=-100, max=100)]))
mySubmit = SubmitField("Save")
@app.route('/', methods=['GET','POST'])
def home():
form = myForm()
xLabels = ["A", "B", "C", "D"]
if request.method == 'GET':
for x in xLabels:
form.myField.append_entry(data=42)
if form.validate_on_submit():
flash("success")
return render_template("drat.html", form=form)
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5000" ,debug=True)
模板:
<!DOCTYPE html>
<html>
<head>
<style>
.error{border-color: red;}
</style>
</head>
<body>
<div>
<form method="POST" action="/">
{{ form.hidden_tag() }}
{% for field in form.myField %}
{% if field.errors %}
<br>{{ field(class="error") }}
{% for error in field.errors %}
<span><br>{{ error }}</span>
{% endfor %}
{% else %}
<br>{{ field }}
{% endif %}
{% endfor %}
<br>{{ form.mySubmit() }}
</form>
{% with messages = get_flashed_messages(with_categories=False) %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</body>
</html>
我的观点如下:
我有一个带有 FloatFields 的 FieldList 输入。 但是那些嵌套字段中的验证器没有 运行.
当我有一个基本表格时,NumberRange
工作正常。
但是当我有一个嵌套表单时,wtforms.validators.NumberRange
会触发以下错误:
TypeError: '<' not supported between instances of 'FloatField' and 'int'
我不知道为什么会出现该错误?
这是我的主要文件:
from flask import Flask, render_template, flash
from flask_wtf import FlaskForm
from wtforms import FloatField, SubmitField, StringField, FieldList, FormField
from wtforms.validators import NumberRange
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
class mySubForm(FlaskForm):
class Meta:
csrf = False
mySubField = FloatField(validators=[NumberRange(min=-100, max=100)])
class myForm(FlaskForm):
myField = FieldList(FormField(mySubForm))
mySubmit = SubmitField("Save")
@app.route('/', methods=['GET','POST'])
def home():
form = myForm()
xLabels = ["A", "B", "C", "D"]
for x in xLabels:
subForm = mySubForm()
form.myField.append_entry(subForm)
if form.validate_on_submit():
flash("success")
return render_template("draft.html", form=form)
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5000" ,debug=True)
这是我的模板:
<!DOCTYPE html>
<html>
<head>
<style>
.error{border-color: red;}
</style>
</head>
<body>
<div>
<form method="POST" action="/">
{{ form.hidden_tag() }}
{% for field in form.myField %}
{% if field.mySubField.errors %}
{{ field.mySubField(class="error") }}
{% for error in field.mySubField.errors %}
<span>{{ error }}</span>
{% endfor %}
{% else %}
{{ field.mySubField.data }}
{% endif %}
{% endfor %}
{{ form.mySubmit() }}
</form>
{% with messages = get_flashed_messages(with_categories=False) %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</body>
</html>
问题是 append_entry
不接受字段,它接受原始数据,因此验证失败,因为它将数字与 FloatField
进行比较。
向其传递一个字段也是您必须在模板中使用 mySubField.data
而不是简单地 mySubField()
的原因,因为实际上 mySubField
正在呈现另一个字段, 你通过的那个。
要修复它,您可以执行以下操作
form.myField.append_entry({'mySubField': some_number})
如上所述,您也可以修复模板:
{% else %}
{{ field.mySubField() }}
{% endif %}
顺便说一句,您可能希望将 add_entry
逻辑包含在条件中,这样它只发生在 GET
请求中,否则每次提交表单时都会添加新条目.
感谢 Luis,这是工作代码:
我的主文件:
from flask import Flask, render_template, flash, request
from flask_wtf import FlaskForm
from wtforms import FloatField, SubmitField, StringField, FieldList, FormField
from wtforms.validators import NumberRange
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
class myForm(FlaskForm):
myField = FieldList(FloatField(validators=[NumberRange(min=-100, max=100)]))
mySubmit = SubmitField("Save")
@app.route('/', methods=['GET','POST'])
def home():
form = myForm()
xLabels = ["A", "B", "C", "D"]
if request.method == 'GET':
for x in xLabels:
form.myField.append_entry(data=42)
if form.validate_on_submit():
flash("success")
return render_template("drat.html", form=form)
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5000" ,debug=True)
模板:
<!DOCTYPE html>
<html>
<head>
<style>
.error{border-color: red;}
</style>
</head>
<body>
<div>
<form method="POST" action="/">
{{ form.hidden_tag() }}
{% for field in form.myField %}
{% if field.errors %}
<br>{{ field(class="error") }}
{% for error in field.errors %}
<span><br>{{ error }}</span>
{% endfor %}
{% else %}
<br>{{ field }}
{% endif %}
{% endfor %}
<br>{{ form.mySubmit() }}
</form>
{% with messages = get_flashed_messages(with_categories=False) %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</body>
</html>