WTForms:如果数据存在,则使用数据填充表单

时间:2017-03-23 18:43:20

标签: python forms wtforms flask-wtforms

我有以下Flask-WTF表格:

class PersonForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    age = IntegerField('Age', validators=[NumberRange(min=0)], render_kw={'type': 'number'})
    educated = BooleanField('Educated', render_kw={'type': 'checkbox'})

我知道我可以通过将值传递到表单中来预先填充表单:

form = PersonForm(name='Johnny', age=25, educated=True)

我注意到有一种更好的方法可以通过在表单中​​注入一个对象来实现这一点(引用herehere)。我尝试了以下,但是,它不起作用。我哪里出错了(对象应该是字典以外的东西)?

person = {'name': 'Johnny', 'age': 25, 'educated'=True}
form = PersonForm(obj=person)

请注意,这些预先填充的值来自数据库。有些值是定义的,而有些则不定义。例如,另一个“人”可能看起来像{'name': 'Jessica', 'educated': True}(在这种情况下,年龄字段将为空)。

2 个答案:

答案 0 :(得分:3)

我认为您希望使用data参数,如this文档中所述:

  

Form类

     

class wtforms.form.Form

     

声明式表格基类。   构造

__init__(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs)
    Parameters:   
     

...

     

数据 - 接受数据字典。仅在不存在formdata和obj时使用。   ...

<强>演示:

>>> 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'test@domain.com')
>>>
>>> person = {'username': 'Johnny', 'email': 'Johny@domain.net'}
>>>
>>> form = UsernameForm(data=person)
>>> 
>>> form.username.data
'Johnny'
>>> 
>>> form.email.data
'Johny@domain.net'

它也适用于formdata参数,但您必须传递MultiDict对象:

>>> from werkzeug.datastructures import MultiDict
>>> 
>>> b = MultiDict(person)
>>> 
>>> b
MultiDict([('email', 'Johny@domain.net'), ('username', 'Johnny')])
>>> 
>>> 
>>> form2 = UsernameForm(formdata=b)
>>> form2.username.data
'Johnny'
>>> form2.email.data
'Johny@domain.net'
>>> 

同时将**kwargs作为常规字典传递:

>> form3 = UsernameForm(**person)
>>> 
>>> form3.username.data
'Johnny'
>>> 
>>> form3.email.data
'Johny@domain.net'

编辑:回复OP关于使用obj参数和引用文档的评论:

 __init__(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs)
     

参数:
  ...

     

obj - 如果formdata为空或未提供,则会检查此对象是否存在与表单字段名称匹配的属性,这些属性将用于字段值。

     

...

这意味着您需要传入一个对象,其属性名称与表单的属性名称相同,如下所示:

>>> class Person:
        username = 'Johny'
        email = 'Johny@domain.net'

>>> 
>>> form = UsernameForm(obj=Person)
>>> 
>>> form.data
{'email': 'Johny@domain.net', 'username': 'Johny'}

答案 1 :(得分:0)

你需要一个MultiDict

>>> a
{'hello': 'data', 'more': 'data'}
>>> from werkzeug.datastructures import MultiDict
>>> b=MultiDict(a)
>>> b
MultiDict([('hello', 'data'), ('more', 'data')])
>>>