WTForms:IntegerField跳过字符串值的强制

时间:2014-03-23 00:50:07

标签: python wtforms flask-wtforms

我有一个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,以便此表单通过验证?

1 个答案:

答案 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: {}