Flask wtforms DataRequired validator tiggers (instead of custom or default validator) when wrong data type submitted as input

huangapple go评论56阅读模式
英文:

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(&#39;Some Number&#39;, 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(&#39;.&#39;)[1]) if &#39;.&#39; in str(field.data) else 0
        if whole_number &gt; 999 or decimal_places &gt; 1:
            raise ValidationError(&#39;Some Number must be less than or equal to 999 and have only one decimal place&#39;)

flask template

&lt;form method=&quot;POST&quot; action=&quot;{{ url_for(&#39;someTemplate&#39;) }}&quot;&gt;
    &lt;div&gt;
        &lt;label for=&quot;{{ form.someNumber.id }}&quot;&gt;{{ form.weight.label }}&lt;/label&gt;
        {{ form.someNumber }}
    &lt;/div&gt;
    {% for error in form.someNumber.errors %}
    &lt;div class=&quot;alert alert-danger&quot;&gt;
        {{ error }} debugging info: {{ form.someNumber.data }}
    &lt;/div&gt;
    {% endfor %}
&lt;/form&gt;

And finally my route

@app.route(&quot;/someTemplate&quot;, methods=[&#39;GET&#39;, &#39;POST&#39;])
def someTemplate():
    form = MyForm()
    if form.validate_on_submit():
        flash(f&quot;You have submitted an entry&quot;, &quot;success&quot;)
        print(form.data)
        return render_template(&quot;someTemplate.html&quot;, form=form)
    return render_template(&quot;someTemplate.html&quot;, 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(&#39;.&#39;)[1]) if &#39;.&#39; in str(field.data) else 0
     else:
        raise ValidationError(&#39;someNumber must be a number&#39;)

    if whole_number &gt; 999 or decimal_places &gt; 1:
        raise ValidationError(&#39;someNumber must be less than or equal to 999 and have only one decimal place&#39;)

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".

huangapple
  • 本文由 发表于 2023年3月12日 07:13:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710148.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定