I have a Form
instance with a single IntegerField
.
The IntegerField renders to HTML as an with
type=\"text\"
This is from one of the WTForms devs:
Fields only coerce form data, they don't coerce object data, this lets people use objects >"like an int" and still have them work without the value being clobbered. It's your >responsibility to pass correct datatypes to object/kwargs data.
And from the docs:
process_formdata(valuelist) Process data received over the wire from a form.
This will be called during form construction with data supplied through the formdata argument.
Parameter: valuelist – A list of strings to process.
In your example the process_formdata
method on IntegerField
will never be called
You are passing in a str
and this will not be coerced because you are supplying it as the data
keyword argument. The data
keyword argument signifies exactly the data you want to validate without coercion. Because '66'
is still a str
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 accepts MultiDict
like objects. If you look at the example below I've used the webob MutliDict
but there is also one supplied in the Werkzeug library. If you wrap a regular python dictionary in a MultiDict
and supply it as the formdata
keyword your form will validate as expected.
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: {}