I think you want to use the data parameter instead, as mentioned in this documentation:
The Form class
class wtforms.form.Form
Declarative Form base class.
Construction
__init__(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs)
Parameters:
...
data – Accept a dictionary of data. This is only used if formdata and obj are not present.
...
Demonstration:
>>> from wtforms import Form, StringField, validators
>>>
>>> class UsernameForm(Form):
username = StringField('Username', [validators.Length(min=5)], default=u'test')
email = StringField('Email', [validators.email(message='Check your email')], default=u'[email protected]')
>>>
>>> person = {'username': 'Johnny', 'email': '[email protected]'}
>>>
>>> form = UsernameForm(data=person)
>>>
>>> form.username.data
'Johnny'
>>>
>>> form.email.data
'[email protected]'
It does work with the formdata parameter as well, but you will have to pass a MultiDict object:
>>> from werkzeug.datastructures import MultiDict
>>>
>>> b = MultiDict(person)
>>>
>>> b
MultiDict([('email', '[email protected]'), ('username', 'Johnny')])
>>>
>>>
>>> form2 = UsernameForm(formdata=b)
>>> form2.username.data
'Johnny'
>>> form2.email.data
'[email protected]'
>>>
Also with **kwargs passed as a regular dictionary:
>> form3 = UsernameForm(**person)
>>>
>>> form3.username.data
'Johnny'
>>>
>>> form3.email.data
'[email protected]'
EDIT: in reply to OP's comment concerning the use of obj parameters and quoting from docs:
__init__(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs)
Parameters:
...
obj – If formdata is empty or not provided, this object is checked for attributes matching form field names, which will be used for field values.
...
That means you need to pass in an object with attribute names same as your forms' attribute name, as follows:
>>> class Person:
username = 'Johny'
email = '[email protected]'
>>>
>>> form = UsernameForm(obj=Person)
>>>
>>> form.data
{'email': '[email protected]', 'username': 'Johny'}
form = PersonForm(data=person)instead?