WTForms:IntegerField在字符串值上跳过强制转换

1 投票
1 回答
2726 浏览
提问于 2025-04-17 23:28

我有一个 Form 实例,里面有一个 IntegerField 字段。

这个 IntegerField 在网页上显示为一个 <input> 输入框,类型是 type="text",而从网页表单提交的数据会以文本字符串的形式返回。但是,如果提交的数据在这个 IntegerField 中是字符串类型,表单就无法通过验证(这些数据是通过一个字典传入的)。

这里有个简单的例子:

from wtforms import validators, Form, IntegerField 

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


test_form1 = TestForm()
print("HTML Render 1: %s" % test_form1.num())

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

输出结果是:

HTML Render 1: <input id="num" name="num" type="text" value="">
HTML Render 2: <input id="num" name="num" type="text" value="66">
     Validate: False
       Errors: {'num': [u'Number must be between 1 and 100.']}

IntegerField 的文档说明是:

IntegerField(Field):一个文本字段,所有输入都会被强制转换为整数

我该如何把一个 str 字符串转换成 int 整数,以便这个表单能够通过验证呢?

1 个回答

3

以下内容来自一位WTForms的开发者:

字段只会处理表单数据,而不会处理对象数据,这样可以让人们像使用整数一样使用对象,并且在不影响值的情况下仍然可以正常工作。你需要自己负责将正确的数据类型传递给对象或关键字参数。

还有文档中的内容:

process_formdata(valuelist) 处理从表单接收到的数据。

在构建表单时,会调用这个方法,并通过formdata参数提供数据。

参数:valuelist – 要处理的字符串列表。

在你的例子中,IntegerField上的process_formdata方法将不会被调用。

你传入的是一个str类型的数据,而这个数据不会被转换,因为你是作为data关键字参数传递的。data关键字参数表示你想要验证的数据,而不进行转换。因为'66'仍然是str类型,所以验证器不会通过。

formdata关键字参数表示从网络接收到的数据。这些数据会经过字段的转换过程。唯一的限制是,它只接受MultiDict类型的对象。如果你查看下面的例子,我使用了webobMultiDict,而Werkzeug库中也提供了一个。如果你将一个普通的Python字典包装在MultiDict中,并作为formdata关键字参数传递,你的表单将会按预期进行验证。

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

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

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

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

撰写回答