# HG changeset patch # User Rabah Meradi # Date 1450166158 -3600 # Node ID 0939ad2edf636abf218688f89890c7ee77c77ca8 # Parent b4de8b1cc1355fbd5df11f902445d03cf8de8bf8 [adapters] Use an adapter for serializing entities to a bare python structure which may be used for e.g. JSON export or other and allow to have different serializations for each entity types. Closes #6378035 diff -r b4de8b1cc135 -r 0939ad2edf63 entities/adapters.py --- a/entities/adapters.py Tue Dec 08 16:28:20 2015 +0100 +++ b/entities/adapters.py Tue Dec 15 08:55:58 2015 +0100 @@ -349,6 +349,32 @@ return path +class ISerializableAdapter(view.EntityAdapter): + """Adapter to serialize an entity to a bare python structure that may be + directly serialized to e.g. JSON. + """ + + __regid__ = 'ISerializable' + __select__ = is_instance('Any') + + def serialize(self): + entity = self.entity + entity.complete() + data = { + 'cw_etype': entity.cw_etype, + 'cw_source': entity.cw_metainformation()['source']['uri'], + } + for rschema, __ in entity.e_schema.attribute_definitions(): + attr = rschema.type + try: + value = entity.cw_attr_cache[attr] + except KeyError: + # Bytes + continue + data[attr] = value + return data + + # error handling adapters ###################################################### from cubicweb import UniqueTogetherError diff -r b4de8b1cc135 -r 0939ad2edf63 entities/test/unittest_base.py --- a/entities/test/unittest_base.py Tue Dec 08 16:28:20 2015 +0100 +++ b/entities/test/unittest_base.py Tue Dec 15 08:55:58 2015 +0100 @@ -232,5 +232,24 @@ eclass = self.select_eclass('Division') self.assertEqual(eclass.cw_etype, 'Division') + +class ISerializableTC(CubicWebTC): + + def test_serialization(self): + with self.admin_access.repo_cnx() as cnx: + entity = cnx.create_entity('CWGroup', name=u'tmp') + cnx.commit() + serializer = entity.cw_adapt_to('ISerializable') + expected = { + 'cw_etype': u'CWGroup', + 'cw_source': 'system', + 'cwuri': u'http://testing.fr/cubicweb/%s' % entity.eid, + 'creation_date': entity.creation_date, + 'modification_date': entity.modification_date, + 'name': u'tmp', + } + self.assertEqual(serializer.serialize(), expected) + + if __name__ == '__main__': unittest_main() diff -r b4de8b1cc135 -r 0939ad2edf63 web/views/json.py --- a/web/views/json.py Tue Dec 08 16:28:20 2015 +0100 +++ b/web/views/json.py Tue Dec 15 08:55:58 2015 +0100 @@ -106,7 +106,8 @@ The following additional metadata is added to each row : - - ``__cwetype__`` : entity type + - ``cw_etype`` : entity type + - ``cw_source`` : source url """ __regid__ = 'ejsonexport' __select__ = EntityView.__select__ | empty_rset() @@ -115,12 +116,8 @@ def call(self): entities = [] for entity in self.cw_rset.entities(): - entity.complete() # fetch all attributes - # hack to add extra metadata - entity.cw_attr_cache.update({ - '__cwetype__': entity.cw_etype, - }) - entities.append(entity) + serializer = entity.cw_adapt_to('ISerializable') + entities.append(serializer.serialize()) self.wdata(entities)