我有一个Form
个实例,只有一个IntegerField
。
IntegerField使用<input>
将HTML呈现为type="text"
,并将数据作为文本字符串从HTML表单发回。但是,如果发布的数据具有IntegerField的字符串值(通过data参数中的dict传入),则表单不会验证。
这是一个玩具示例:
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的docstring说:
IntegerField(Field):文本字段,除了所有输入都被强制转换为整数
如何将str
强制转换为int
,以便此表单通过验证?
答案 0 :(得分:2)
This来自 WTForms 开发者之一:
字段只强制表单数据,它们不强制对象数据,这可以让人们使用对象&gt;“就像一个int”,并且仍然让它们在没有被破坏的值的情况下工作。将正确的数据类型传递给object / kwargs数据是你的责任。
来自文档:
<强> process_formdata(值列表)强> 处理从表单通过电汇收到的数据。
这将在表单构造期间调用,并通过formdata提供数据 参数。
参数:valuelist - 要处理的字符串列表。
在您的示例中,永远不会调用process_formdata
上的IntegerField
方法
您正在传递str
并且这不会被强制执行,因为您将其作为data
关键字参数提供。 data
关键字参数无需强制即表示您要验证的数据。由于'66'
仍然是str
,验证者不会让它通过。
formdata
关键字参数表示数据通过网络传输。这将通过该字段的强制过程。只有一个捕获,它只接受MultiDict
个类似的对象。如果您查看下面的示例,我使用了 webob MutliDict
,但 Werkzeug 库中也提供了一个。如果您在MultiDict
中包含常规python字典并将其作为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: {}