I have a Form
instance with a single IntegerField
.
The IntegerField renders to HTML as an <input>
with type="text"
and data gets POSTed back from an HTML form as a text string. However the form will not validate if the posted data has a string value for the IntegerField (passed in via a dict in the data parameter).
Here's a toy example:
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)
The output is:
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.']}
The docstring for IntegerField says:
IntegerField(Field): A text field, except all input is coerced to an integer
How can I coerce a str
into an int
such that this form will pass validation?
This is from one of the WTForms devs:
And from the docs:
In your example the
process_formdata
method onIntegerField
will never be calledYou are passing in a
str
and this will not be coerced because you are supplying it as thedata
keyword argument. Thedata
keyword argument signifies exactly the data you want to validate without coercion. Because'66'
is still astr
the validators won't let it pass.The
formdata
keyword argument indicates the data coming in off the wire. This will go through the field's coercion process. There is only one catch, it only acceptsMultiDict
like objects. If you look at the example below I've used the webobMutliDict
but there is also one supplied in the Werkzeug library. If you wrap a regular python dictionary in aMultiDict
and supply it as theformdata
keyword your form will validate as expected.