英文:
Flask wtforms DataRequired validator tiggers (instead of custom or default validator) when wrong data type submitted as input
问题
尝试将DataRequired()
和自定义验证器validate_someNumber
附加到FloatField
上。但是,当出现验证错误时,我很难理解表单字段错误的反馈。以下是对该字段的要求:
- 应该有数据
- 该字段只允许单个数值
- 该字段只允许最大到百位的整数位。例如:最大值999
- 该字段只允许一个小数位。例如:999.9
form.py
from flask_wtf import FlaskForm
from wtforms import FloatField
from wtforms.validators import DataRequired
from validators import validate_someNumber
class MyForm(FLaskForm):
someNumber = FloatField('Some Number', validators=[DataRequired(), validate_someNumber])
validator
from wtforms.validators import ValidationError
def validate_someNumber(form, field):
if field.data is not None:
whole_number = int(field.data)
decimal_places = len(str(field.data).split('.'))[1] if '.' in str(field.data) else 0
if whole_number > 999 or decimal_places > 1:
raise ValidationError('Some Number must be less than or equal to 999 and have only one decimal place')
flask模板
<form method="POST" action="{{ url_for('someTemplate') }}">
<div>
<label for="{{ form.someNumber.id }}">{{ form.weight.label }}</label>
{{ form.someNumber }}
</div>
{% for error in form.someNumber.errors %}
<div class="alert alert-danger">
{{ error }} debugging info: {{ form.someNumber.data }}
</div>
{% endfor %}
</form>
最后是我的路由
@app.route("/someTemplate", methods=['GET', 'POST'])
def someTemplate():
form = MyForm()
if form.validate_on_submit():
flash("You have submitted an entry", "success")
print(form.data)
return render_template("someTemplate.html", form=form)
return render_template("someTemplate.html", form=form)
然后,我尝试提交输入,比如"totallyNotNumeric",UI会渲染"DataRequired"警告消息,"This field is required"。为什么它不会引发"这不是有效的浮点数"的消息呢?
这似乎是与字段类最接近的消息。我测试了一个没有验证器的普通FloatField
,当我尝试使用字母数字输入时,它将"不是有效的浮点数"消息传递到错误列表中?
此外,我注意到我的自定义验证器起作用。当输入类似"111.111"时,我会收到我的自定义错误消息。所以我尝试在我的自定义验证器中验证数据类型。所以我将它修改如下:
if field.data is not None:
whole_number = None
decimal_places = None
if isinstance(field.data, (int, float)):
whole_number = int(field.data)
decimal_places = len(str(field.data).split('.'))[1] if '.' in str(field.data) else 0
else:
raise ValidationError('someNumber must be a number')
if whole_number > 999 or decimal_places > 1:
raise ValidationError('someNumber must be less than or equal to 999 and have only one decimal place')
这没有起作用。有什么建议吗?我是否遗漏了一些非常简单的东西,或者对Flask表单或wtforms的核心概念有误解?谢谢!
英文:
Trying to attach a DataRequired()
and custom validator, validate_someNumber
to a FloatField
. But I am having a hard time understanding the feedback from the form field errors when the validation errors are raised. Here are my requirements for the field in question:
- There should be data
- The field should only allow a single numeric value
- The field should only allow a maximum whole number placement to the hundred's. ex: maximum 999
- The field should only allow a single decimal place. ex: 999.9
form.py
from flask_wtf import FlaskForm
from wtforms import FloatField
from wtforms.validators import DataRequired
from validators import validate_someNumber
class MyForm(FLaskForm):
someNumber = FloatField('Some Number', validators=[DataRequired(), validate_someNumber])
validator
from wtforms.validators import ValidationError
def validate_someNumber(form, field):
if field.data is not None:
whole_number = int(field.data)
decimal_places = len(str(field.data).split('.')[1]) if '.' in str(field.data) else 0
if whole_number > 999 or decimal_places > 1:
raise ValidationError('Some Number must be less than or equal to 999 and have only one decimal place')
flask template
<form method="POST" action="{{ url_for('someTemplate') }}">
<div>
<label for="{{ form.someNumber.id }}">{{ form.weight.label }}</label>
{{ form.someNumber }}
</div>
{% for error in form.someNumber.errors %}
<div class="alert alert-danger">
{{ error }} debugging info: {{ form.someNumber.data }}
</div>
{% endfor %}
</form>
And finally my route
@app.route("/someTemplate", methods=['GET', 'POST'])
def someTemplate():
form = MyForm()
if form.validate_on_submit():
flash(f"You have submitted an entry", "success")
print(form.data)
return render_template("someTemplate.html", form=form)
return render_template("someTemplate.html", form=form)
Then I try to submit input like "totallyNotNumeric" and the UI renders the DataRequired
warning message, "This field is required". Why would it not raise the "This is not a valid float" message instead?
That seems to be the message closest to the field Class. I tested a plain FloatField
without validators and it passed the '... not a valid float' message to the errors list when I tried using alpha-numeric input???
Furthermore, I noticed my custom validator works. When entering something like, "111.111". I get my custom error message. So I thought let me try validating the data type in my custom validator as well. So I modified it like this:
if field.data is not None:
whole_number = None
decimal_places = None
if isinstance(field.data, (int, float)):
whole_number = int(field.data)
decimal_places = len(str(field.data).split('.')[1]) if '.' in str(field.data) else 0
else:
raise ValidationError('someNumber must be a number')
if whole_number > 999 or decimal_places > 1:
raise ValidationError('someNumber must be less than or equal to 999 and have only one decimal place')
This did not work. Any advice? Am I missing something super simple or misunderstanding a core concept of flask forms? wtforms? Thanks
答案1
得分: 1
不需要在这里使用DataRequired验证器的特定原因。当使用时,如果数据为空,先前的错误(例如处理错误)将从字段中删除。
将其从DataRequired
更改为InputRequired
,这将为您提供熟悉的错误消息:“这不是有效的浮点数”。
英文:
There is no specific reason to use the DataRequired validator here. When used, previous errors (e.g. processing errors) are removed from the field if the data is empty.
Change from DataRequired
to InputRequired
and it should give you the familiar error message "This is not a valid float".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论