问题
I have a custom field inside a FormField inside a FieldList: locations
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)
This form when submited is saved to an object like this:
document = {
'title': unicode,
'description': unicode,
'manager': unicode,
'locations': [{
'id': uuid.UUID,
'title': unicode,
'location': {'coordinates':[float], 'text':unicode}
}],
}
When I try to load the data in to the form for a GET handler, everything but the locations loads fine:
f = form(MultiDict(document))
f.locations.data
>> {'id':'','title':'','location':''}
I did some debugging and found that WTForms while loading the document's data in to the form searches for 'locations-0-location' but MultiDict() but that keys doesn't exists. MultiDict doesn't convert a list of dictionaries to the key 'locations-i-...'.
What is the right way to make a WTForm for such a nested data structure?
回答1:
I had the same problem and was able to sort it by flattening the list to a dict with the added prefix.
Something like:
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()})
回答2:
with WTFORMS 2.1
the data:
document = {
'title': unicode,
'description': unicode,
'manager': unicode,
'locations': [{
'id': uuid.UUID,
'title': unicode,
'location': {'coordinates':[float], 'text':unicode}
}],
}
you set the data structure with 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)
try this:
f = ProjectForm()
f.process(data=document)
f.locations.data
回答3:
I think the answer is in this part of the documentation about the .process()
method:
Since BaseForm does not take its data at instantiation, you must call this to provide form data to the enclosed fields.
You should use:
f = form()
f.process(data=MultiDict(document))
instead of:
f = form(MultiDict(document))
来源:https://stackoverflow.com/questions/25203059/wtforms-fieldlist-of-formfield-cant-load-nested-data