api: add a transient formdata to evaluated submitted fields (#58877)

This commit is contained in:
Frédéric Péters 2021-11-23 13:30:32 +01:00
parent 81d629d09e
commit 97678018cb
2 changed files with 45 additions and 19 deletions

View File

@ -922,6 +922,15 @@ def test_formdef_submit_structured(pub, local_user):
'value': '[dict(id=i, text=\'label %s\' % i, foo=i) for i in range(10)]',
},
),
fields.ItemField(
id='2',
label='foobar2',
varname='foobar2',
data_source={
'type': 'json',
'value': 'http://datasource.com/{{form_var_foobar_foo}}',
},
),
]
formdef.store()
data_class = formdef.data_class()
@ -946,10 +955,14 @@ def test_formdef_submit_structured(pub, local_user):
{
'data': {
'0': '0',
"1": '3',
'1': '3',
'2': '2',
}
},
)
assert len(urlopen.mock_calls) == 2
assert urlopen.call_args_list[0][0] == ('http://datasource.com',)
assert urlopen.call_args_list[1][0] == ('http://datasource.com/bar',)
formdata = data_class.get(resp.json['data']['id'])
assert formdata.status == 'wf-new'
@ -967,5 +980,12 @@ def test_formdef_submit_structured(pub, local_user):
'text': 'label 3',
'foo': 3,
}
assert formdata.data['2'] == '2'
assert formdata.data['2_display'] == 'deux'
assert formdata.data['2_structured'] == {
'id': 2,
'text': 'deux',
'foo': 'bar2',
}
data_class.wipe()

View File

@ -74,24 +74,30 @@ def posted_json_data_to_formdata_data(formdef, data):
if field.store_structured_value and structured in data:
data['%s_structured' % field.id] = data.pop(structured)
# complete/adapt field values
for field in formdef.get_all_fields():
structured = '%s_structured' % field.id
display = '%s_display' % field.id
if data.get(field.id) is None:
continue
if hasattr(field, 'from_json_value'):
data[field.id] = field.from_json_value(data[field.id])
# only fill display/structured if both are absent
if display not in data and structured not in data:
if field.store_display_value:
display_value = field.store_display_value(data, field.id)
if display_value is not None:
data[display] = display_value
if field.store_structured_value:
structured_value = field.store_structured_value(data, field.id)
if structured_value is not None:
data[structured] = structured_value
# create a temporary formdata so datasources using previous fields in
# parameters can find their values.
transient_formdata = formdef.data_class()()
transient_formdata.data = data
with get_publisher().substitutions.temporary_feed(transient_formdata, force_mode='lazy'):
# complete/adapt field values
for field in formdef.get_all_fields():
structured = '%s_structured' % field.id
display = '%s_display' % field.id
if data.get(field.id) is None:
continue
if hasattr(field, 'from_json_value'):
data[field.id] = field.from_json_value(data[field.id])
# only fill display/structured if both are absent
if display not in data and structured not in data:
if field.store_display_value:
display_value = field.store_display_value(data, field.id)
if display_value is not None:
data[display] = display_value
if field.store_structured_value:
structured_value = field.store_structured_value(data, field.id)
if structured_value is not None:
data[structured] = structured_value
return data