WTForms:FormField的FieldList无法加载嵌套数据

时间:2014-08-08 12:01:10

标签: python flask wtforms

我在FieldList中的FormField中有一个自定义字段:位置

class LocationForm(Form):
    id = HiddenField('id')
    title = StringField(_l('Title'), [Required()])
    location = CoordinatesField(_l('Coordinates'))

class ProjectForm(Form):
    title = StringField(_l('Title'))
    manager = StringField(_l('Manager'))
    description = StringField(_l('Description'))
    locations = FieldList(FormField(LocationForm), min_entries=1)

当提交时,此表单将保存到这样的对象:

document = {
    'title': unicode,
    'description': unicode,
    'manager': unicode,
    'locations': [{
        'id': uuid.UUID,
        'title': unicode,
        'location': {'coordinates':[float], 'text':unicode}
        }],
    }

当我尝试将数据加载到GET处理程序的表单时, 一切但位置加载正常:

f = form(MultiDict(document))
f.locations.data
>> {'id':'','title':'','location':''}

我做了一些调试,发现WTForms在将文档的数据加载到表单时会搜索“location-0-location”#39;但是MultiDict()但是密钥不存在。 MultiDict不会将字典列表转换为关键字&位置-i -...'。

为这样的嵌套数据结构制作WTForm的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,并且可以通过将列表展平为带有添加前缀的dict来对其进行排序。

类似的东西:

document = {
    'title': unicode,
    'description': unicode,
    'manager': unicode,
}

locations = [{
    'id': uuid.UUID,
    'title': unicode,
    'location': {'coordinates':[float], 'text':unicode}
}]

document.update({'locations-%s-%s' % (num, key): val for num, l in enumerate(locations) for key, val in l.items()})

答案 1 :(得分:1)

使用WTFORMS 2.1

数据:

document = {
    'title': unicode,
    'description': unicode,
    'manager': unicode,
    'locations': [{
        'id': uuid.UUID,
        'title': unicode,
        'location': {'coordinates':[float], 'text':unicode}
        }],
    }

使用WTFORMS设置数据结构:

class LocationForm(Form):
    id = HiddenField('id')
    title = StringField(_l('Title'), [Required()])
    location = CoordinatesField(_l('Coordinates'))

class ProjectForm(Form):
    title = StringField(_l('Title'))
    manager = StringField(_l('Manager'))
    description = StringField(_l('Description'))
    locations = FieldList(FormField(LocationForm), min_entries=1)

试试这个:

f = ProjectForm()
f.process(data=document)
f.locations.data

答案 2 :(得分:0)

我认为答案在有关.process()方法的文档的this part中:

由于BaseForm不会在实例化时获取其数据,因此必须调用它以将表单数据提供给所包含的字段。

您应该使用:

f = form()
f.process(data=MultiDict(document))

代替:

f = form(MultiDict(document))