[adapters] Use an adapter for serializing entities to a bare python structure
authorRabah Meradi <rabah.meradi@logilab.fr>
Tue, 15 Dec 2015 08:55:58 +0100
changeset 10973 0939ad2edf63
parent 10969 b4de8b1cc135
child 10974 6557833657d6
[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
entities/adapters.py
entities/test/unittest_base.py
web/views/json.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
--- 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()
--- 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)