api: add proper representation for block field data (#48532)

This commit is contained in:
Frédéric Péters 2020-11-13 14:17:01 +01:00
parent 0aa4714e71
commit be68194bc8
3 changed files with 44 additions and 8 deletions

View File

@ -28,6 +28,7 @@ from wcs.qommon.ident.password_accounts import PasswordAccount
from wcs.qommon import ods
from wcs.users import User
from wcs.roles import Role
from wcs.blocks import BlockDef
from wcs.carddef import CardDef
from wcs.formdef import FormDef
from wcs.formdata import Evolution
@ -1182,6 +1183,16 @@ def test_formdata(pub, local_user):
{'id': '2', 'text': 'bar', 'more': 'YYY'}])}
data_source.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='abc', label='Foo', varname='foo'),
fields.ItemField(id='xyz', label='Test', type='item',
data_source={'type': 'foobar'}, varname='bar'),
]
block.store()
Role.wipe()
role = Role(name='test')
role.id = '123'
@ -1200,6 +1211,7 @@ def test_formdata(pub, local_user):
fields.FileField(id='3', label='foobar4', varname='file'),
fields.ItemField(id='4', label='foobar5', varname='item',
data_source={'type': 'foobar'}),
fields.BlockField(id='5', label='test', varname='blockdata', type='block:foobar', max_items=3),
]
workflow = Workflow.get_default_workflow()
workflow.roles['_foobar'] = 'Foobar'
@ -1222,6 +1234,11 @@ def test_formdata(pub, local_user):
'2': date,
'3': upload,
'4': '1',
'5': {
'data': [{'abc': 'plop', 'xyz': '1', 'xyz_display': 'foo', 'xyz_structured': 'XXX'},],
'schema': {}, # not important here
},
'5_display': 'hello',
}
formdata.data['4_display'] = item_field.store_display_value(
formdata.data, item_field.id)
@ -1246,7 +1263,7 @@ def test_formdata(pub, local_user):
assert datetime.datetime.strptime(resp.json['last_update_time'], '%Y-%m-%dT%H:%M:%S')
assert datetime.datetime.strptime(resp.json['receipt_time'], '%Y-%m-%dT%H:%M:%S')
assert len(resp.json['fields']) == 6
assert len(resp.json['fields']) == 8
assert 'foobar' in resp.json['fields']
assert 'foobar2' not in resp.json['fields'] # foobar2 has no varname, not in json
assert resp.json['user']['name'] == local_user.name
@ -1258,6 +1275,8 @@ def test_formdata(pub, local_user):
assert resp.json['fields']['item'] == 'foo'
assert resp.json['fields']['item_raw'] == '1'
assert resp.json['fields']['item_structured'] == {'id': '1', 'text': 'foo', 'more': 'XXX'}
assert resp.json['fields']['blockdata'] == 'hello'
assert resp.json['fields']['blockdata_raw'] == [{'foo': 'plop', 'bar': 'foo', 'bar_raw': '1', 'bar_structured': 'XXX'}]
assert resp.json['workflow']['status']['name'] == 'New'
assert resp.json['submission']['channel'] == 'web'
assert resp.json['geolocations']['base']['lon'] == 10

View File

@ -2730,6 +2730,18 @@ class BlockField(WidgetField):
cells[i] = self.block.get_display_value(subvalue)
return cells
def get_json_value(self, value, **kwargs):
from wcs.formdata import FormData
result = []
if not value or not value.get('data'):
return result
for subvalue_data in value.get('data'):
result.append(FormData.get_json_data_dict(
subvalue_data,
self.block.fields,
include_files=kwargs.get('include_file_content')))
return result
def get_field_class_by_type(type):
for k in field_classes:

View File

@ -1028,7 +1028,8 @@ class FormData(StorableObject):
return field.get_json_value(self.data[field.id])
return None
def get_json_dict(self, fields, include_files=True, anonymise=False):
@classmethod
def get_json_data_dict(cls, data, fields, formdata=None, include_files=True, anonymise=False):
new_data = {}
seen = set()
for field in fields:
@ -1040,24 +1041,28 @@ class FormData(StorableObject):
# skip fields with a varname that is used by another non-empty
# field.
continue
if self.data is not None:
value = self.data.get(field.id)
if data is not None:
value = data.get(field.id)
if value and hasattr(field, 'get_json_value'):
value = field.get_json_value(value, formdata=self, include_file_content=include_files)
value = field.get_json_value(value, formdata=formdata, include_file_content=include_files)
else:
value = None
if value:
seen.add(field.varname)
if field.store_display_value:
new_data[field.varname + '_raw'] = value
new_data[field.varname] = self.data.get('%s_display' % field.id)
new_data[field.varname] = data.get('%s_display' % field.id)
else:
new_data[field.varname] = value
if field.store_structured_value:
if self.data.get('%s_structured' % field.id):
new_data[field.varname + '_structured'] = self.data.get('%s_structured' % field.id)
if data.get('%s_structured' % field.id):
new_data[field.varname + '_structured'] = data.get('%s_structured' % field.id)
return new_data
def get_json_dict(self, fields, include_files=True, anonymise=False):
return self.get_json_data_dict(self.data, fields, formdata=self,
include_files=include_files, anonymise=anonymise)
def get_json_export_dict(self, include_files=True, anonymise=False, user=None):
data = {}
data['id'] = str(self.id)