WTForms: IntegerField skips coercion on string value

I have an instance Form

with one IntegerField

.

IntegerField renders HTML as <input>

with type="text"

, and the data is POSTed back from the HTML form as a text string. However, the form will not be validated if the posted data has a string value for an IntegerField (passed via a dict in the data parameter).

Here's an example of a toy:

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)

      

Output:

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 that all input is forced to be an integer

How can I force str

to int

that the form has been checked?

+1


source to share


1 answer


This is from one of the WTForms developers:

Fields only process form data, they do not copy object data, this allows people to use objects> "like int" and still work with them without the value being knocked down. It is your responsibility to pass the correct data types to the / kwargs objects.

And from the docs:

process_formdata (Valuelist) Process data received by wire from the form.

This will be called during form construction with the data passed through the formdata argument.

Parameter: valuelist - list of strings to process.

In your example, the method process_formdata

to IntegerField

be never called



You are passing in str

, and it won't be forced because you are supplying it as a keyword argument data

. The keyword parameter data

means exactly the data you want to check without being forced . Since '66'

there is still remains str

, validators do not skip it.

The keyword argument formdata

specifies the data coming from the wire. This will go through a process of compulsion . There is only one catch, it only takes MultiDict

as objects. If you look at the example below, I used webob MutliDict

, but there is also one in the Werkzeug library . If you close a regular python dictionary in MultiDict

and supply it as a keyword formdata

, 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: {}

      

+1


source







All Articles