【问题标题】:WTForms: populate form with data if data existsWTForms:如果数据存在,则用数据填充表单
【发布时间】:2017-08-16 12:05:18
【问题描述】:

我有以下 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}(在这种情况下,年龄字段将为空)。

【问题讨论】:

  • 是的,它需要是一个 MultiDict。这就是烧瓶请求发布数据返回的内容。它旨在与烧瓶请求中的发布数据一起使用。
  • 如何根据从数据库中检索到的数据创建 MultDict?
  • 你试过form = PersonForm(data=person)吗?

标签: python forms wtforms flask-wtforms


【解决方案1】:

我认为您想改用data 参数,如this 文档中所述:

表单类

类 wtforms.form.Form

声明式表单基类。 建设

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

...

data – 接受数据字典。这仅在 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'}

【讨论】:

  • 很棒的答案,谢谢。那么obj参数是干什么用的呢?
  • 超级有帮助!谢谢
  • @jcmetz21...没有 pblm :)
【解决方案2】:

你需要一个 MultiDict

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

【讨论】:

  • 我只是尝试将这个 MultiDict 传递给表单但没有运气:form = PersonForm(obj=MultiDict(person))
  • 你的数据库数据是字典吗?
  • 试试:form = PersonForm(); form.populate_obj(req)
  • 这似乎也不起作用。我正在使用 mongodb,所以是的,数据是作为 python 字典检索的。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 2019-01-29
  • 2018-02-27
  • 2016-03-06
  • 2021-01-10
  • 1970-01-01
相关资源
最近更新 更多