WTForms: IntegerField在字符串值为'0'时跳过强制转换

4 投票
1 回答
3108 浏览
提问于 2025-04-18 17:28

这个问题几乎涵盖了我想要了解的内容,但还不完全。

看起来,当字符串值是 '0' 时,IntegerField 不会进行类型转换。其他正整数似乎都能正常工作。

这里是一个 '0' 的例子:

from wtforms import validators, Form, IntegerField
from webob.multidict import MultiDict

class TestForm(Form):
    num = IntegerField('How Many?', [validators.DataRequired('num required.'), validators.NumberRange(min=0, max=100)])

data_in = {'num': '0'}  # Note '0' is a string as would be POSTed
test_form = TestForm(formdata=MultiDict(data_in))
print("HTML Render: %s" % test_form.num())
print("     Validate: %s" % test_form.validate())
print("       Errors: %s" % test_form.errors)

这个的输出是:

HTML Render: <input id="num" name="num" type="text" value="0">
     Validate: False
       Errors: {'num': ['num required.']}

另外,使用 '66' 的例子:

from wtforms import validators, Form, IntegerField
from webob.multidict import MultiDict

class TestForm(Form):
    num = IntegerField('How Many?', [validators.DataRequired('num required.'), validators.NumberRange(min=0, max=100)])

data_in = {'num': '66'}  # Note '66' is a string as would be POSTed
test_form = TestForm(formdata=MultiDict(data_in))
print("HTML Render: %s" % test_form.num())
print("     Validate: %s" % test_form.validate())
print("       Errors: %s" % test_form.errors)

这个的输出是:

HTML Render: <input id="num" name="num" type="text" value="66">
     Validate: True
       Errors: {}

这是怎么回事?我可以使用 InputRequired 来保持类型不固定,但那样就完全失去了这个的意义。

1 个回答

2

我想你可能需要保持这个类型不固定,改用 InputRequired 来处理 :-)

这里的文档中提到:

“[...]这个验证器以前叫做 Required,但它的工作方式(要求强制转换的数据,而不是输入的数据)导致它的功能和 Optional 验证器不对称,并且在某些将数据强制转换为 '假值' 的字段(比如 0、Decimal(0)、time(0) 等)时造成了混淆。除非有非常具体的理由,我们建议使用 :class:InputRequired。”

实际出问题的代码在下面的第 201 行:

if not field.data

撰写回答