misc: use existing computed data fields when evaluating further fields (#55440)
This commit is contained in:
parent
7f7781dbdb
commit
739a53eb5a
|
@ -477,3 +477,49 @@ def test_computed_field_edit_action(pub):
|
|||
resp = resp.forms[0].submit('submit')
|
||||
formdata.refresh_from_storage()
|
||||
assert formdata.data == {'0': 'bar', '1': 'PLOP'}
|
||||
|
||||
|
||||
def test_cascading_computed_fields(pub):
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = [
|
||||
fields.PageField(
|
||||
id='0',
|
||||
label='1st page',
|
||||
type='page',
|
||||
post_conditions=[
|
||||
{
|
||||
'condition': {
|
||||
'type': 'django',
|
||||
'value': 'form_var_dc == "0abc"',
|
||||
},
|
||||
'error_message': 'You shall not pass.',
|
||||
}
|
||||
],
|
||||
),
|
||||
fields.ComputedField(id='1', label='computed', varname='a', value_template='a'),
|
||||
fields.ComputedField(id='2', label='computed', varname='b', value_template='{{form_var_a}}b'),
|
||||
fields.ComputedField(id='3', label='computed', varname='c', value_template='{{form_var_b}}c'),
|
||||
fields.CommentField(id='4', label='X{{ form_var_c }}Y', type='comment'),
|
||||
fields.StringField(id='5', label='string', varname='d'),
|
||||
fields.ComputedField(id='6', label='computed', varname='da', value_template='{{form_var_d}}a'),
|
||||
fields.ComputedField(id='7', label='computed', varname='db', value_template='{{form_var_da}}b'),
|
||||
fields.ComputedField(id='8', label='computed', varname='dc', value_template='{{form_var_db}}c'),
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert 'XabcY' in resp.text # check comment field has the correct value
|
||||
|
||||
# this should produce form_var_dc == "Xabc", and not pass the post condition
|
||||
resp.forms[0]['f5'].value = 'X'
|
||||
resp = resp.forms[0].submit('submit') # -> validation
|
||||
assert 'You shall not pass.' in resp.text
|
||||
|
||||
# this should produce form_var_dc == "0abc", and be ok for the post condition
|
||||
resp = get_app(pub).get('/test/')
|
||||
resp.forms[0]['f5'].value = '0'
|
||||
resp = resp.forms[0].submit('submit') # -> validation
|
||||
assert 'You shall not pass.' not in resp.text
|
||||
|
|
|
@ -641,17 +641,33 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
return computed_values
|
||||
if not computed_values:
|
||||
get_session().add_magictoken('%s-computed' % magictoken, computed_values)
|
||||
|
||||
# create a temporary map using form variable names, to be used as context
|
||||
# variables during evaluation (via temporary_feed below), so we can have
|
||||
# computed fields depending on previously computed fields from the same page.
|
||||
mapped_computed_values = {}
|
||||
for field in fields:
|
||||
if field.freeze_on_initial_value and field.id in computed_values:
|
||||
continue
|
||||
with get_publisher().complex_data():
|
||||
try:
|
||||
value = WorkflowStatusItem.compute(field.value_template, raises=True, allow_complex=True)
|
||||
except TemplateError:
|
||||
if field.id in computed_values:
|
||||
mapped_computed_values['form_var_%s' % field.varname] = computed_values[field.id]
|
||||
|
||||
with get_publisher().substitutions.temporary_feed(mapped_computed_values, force_mode='lazy'):
|
||||
for field in fields:
|
||||
if field.freeze_on_initial_value and field.id in computed_values:
|
||||
continue
|
||||
else:
|
||||
value = get_publisher().get_cached_complex_data(value)
|
||||
computed_values[field.id] = value
|
||||
|
||||
with get_publisher().complex_data():
|
||||
try:
|
||||
value = WorkflowStatusItem.compute(
|
||||
field.value_template, raises=True, allow_complex=True
|
||||
)
|
||||
except TemplateError:
|
||||
continue
|
||||
else:
|
||||
value = get_publisher().get_cached_complex_data(value)
|
||||
computed_values[field.id] = value
|
||||
mapped_computed_values['form_var_%s' % field.varname] = value
|
||||
get_publisher().substitutions.invalidate_cache()
|
||||
|
||||
return computed_values
|
||||
|
||||
def modify_filling_context(self, context, page, data):
|
||||
|
|
Loading…
Reference in New Issue