From 7726be94be5e86b74e28d40af272a9365566cbea Mon Sep 17 00:00:00 2001 From: elephant Date: Mon, 6 Apr 2015 20:21:36 +0500 Subject: [PATCH 1/4] fixed wrong _delta results on nested MapFields #931 --- mongoengine/dereference.py | 3 ++- tests/document/delta.py | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mongoengine/dereference.py b/mongoengine/dereference.py index 453ba14f..0f60c2f5 100644 --- a/mongoengine/dereference.py +++ b/mongoengine/dereference.py @@ -220,7 +220,8 @@ class DeReference(object): elif isinstance(v, (dict, SON)) and '_ref' in v: data[k]._data[field_name] = self.object_map.get(v['_ref'].id, v) elif isinstance(v, dict) and depth <= self.max_depth: - data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=name) + item_name = "%s.%s.%s" % (name, k, field_name) + data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=item_name) elif isinstance(v, (list, tuple)) and depth <= self.max_depth: data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=name) elif isinstance(v, (dict, list, tuple)) and depth <= self.max_depth: diff --git a/tests/document/delta.py b/tests/document/delta.py index 7ec6ee56..95a03861 100644 --- a/tests/document/delta.py +++ b/tests/document/delta.py @@ -827,5 +827,29 @@ class DeltaTest(unittest.TestCase): org2.reload() self.assertEqual(org2.name, 'New Org 2') + def test_delta_for_nested_map_fields(self): + class EmbeddedRole(EmbeddedDocument): + type = StringField() + + class EmbeddedUser(EmbeddedDocument): + name = StringField() + roles = MapField(field=EmbeddedDocumentField(EmbeddedRole)) + + class Doc(Document): + users = MapField(field=EmbeddedDocumentField(EmbeddedUser)) + num = IntField(default=-1) + + Doc.drop_collection() + + doc = Doc(num=1) + doc.users["007"] = EmbeddedUser(name="Agent007") + doc.save() + + d = Doc.objects(num=1).first() + d.users["007"]["roles"]["666"] = EmbeddedRole(type="superadmin") + delta = d._delta() + self.assertEqual(True, "users.007.roles.666" in delta[0]) + self.assertEqual('superadmin', delta[0]["users.007.roles.666"]["type"]) + if __name__ == '__main__': unittest.main() From 31f7769199b1c0128ec66c0612a568061d4f22b3 Mon Sep 17 00:00:00 2001 From: Eremeev Danil Date: Thu, 9 Apr 2015 09:14:12 +0500 Subject: [PATCH 2/4] percent string formatting changed to format method --- mongoengine/dereference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/dereference.py b/mongoengine/dereference.py index 0f60c2f5..cc710f4d 100644 --- a/mongoengine/dereference.py +++ b/mongoengine/dereference.py @@ -220,7 +220,7 @@ class DeReference(object): elif isinstance(v, (dict, SON)) and '_ref' in v: data[k]._data[field_name] = self.object_map.get(v['_ref'].id, v) elif isinstance(v, dict) and depth <= self.max_depth: - item_name = "%s.%s.%s" % (name, k, field_name) + item_name = "{0}.{1}.{2}".format(name, k, field_name) data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=item_name) elif isinstance(v, (list, tuple)) and depth <= self.max_depth: data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=name) From ebaba95eb376c761dd4d439a6836f2353dea674b Mon Sep 17 00:00:00 2001 From: Eremeev Danil Date: Thu, 9 Apr 2015 09:34:40 +0500 Subject: [PATCH 3/4] fixed same bug for nested List inside MapField, little code refactoring, added test for nested list and nested reference fields --- mongoengine/dereference.py | 4 +--- tests/document/delta.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mongoengine/dereference.py b/mongoengine/dereference.py index cc710f4d..0428397c 100644 --- a/mongoengine/dereference.py +++ b/mongoengine/dereference.py @@ -219,11 +219,9 @@ class DeReference(object): data[k]._data[field_name] = self.object_map.get(v.id, v) elif isinstance(v, (dict, SON)) and '_ref' in v: data[k]._data[field_name] = self.object_map.get(v['_ref'].id, v) - elif isinstance(v, dict) and depth <= self.max_depth: + elif isinstance(v, (dict, list, tuple)) and depth <= self.max_depth: item_name = "{0}.{1}.{2}".format(name, k, field_name) data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=item_name) - elif isinstance(v, (list, tuple)) and depth <= self.max_depth: - data[k]._data[field_name] = self._attach_objects(v, depth, instance=instance, name=name) elif isinstance(v, (dict, list, tuple)) and depth <= self.max_depth: item_name = '%s.%s' % (name, k) if name else name data[k] = self._attach_objects(v, depth - 1, instance=instance, name=item_name) diff --git a/tests/document/delta.py b/tests/document/delta.py index 95a03861..e5a81c06 100644 --- a/tests/document/delta.py +++ b/tests/document/delta.py @@ -828,12 +828,17 @@ class DeltaTest(unittest.TestCase): self.assertEqual(org2.name, 'New Org 2') def test_delta_for_nested_map_fields(self): + class UInfoDocument(Document): + phone = StringField() + class EmbeddedRole(EmbeddedDocument): type = StringField() class EmbeddedUser(EmbeddedDocument): name = StringField() roles = MapField(field=EmbeddedDocumentField(EmbeddedRole)) + rolist = ListField(field=EmbeddedDocumentField(EmbeddedRole)) + info = ReferenceField(UInfoDocument) class Doc(Document): users = MapField(field=EmbeddedDocumentField(EmbeddedUser)) @@ -845,11 +850,21 @@ class DeltaTest(unittest.TestCase): doc.users["007"] = EmbeddedUser(name="Agent007") doc.save() + uinfo = UInfoDocument(phone="79089269066") + uinfo.save() + d = Doc.objects(num=1).first() d.users["007"]["roles"]["666"] = EmbeddedRole(type="superadmin") + d.users["007"]["rolist"].append(EmbeddedRole(type="oops")) + d.users["007"]["info"] = uinfo delta = d._delta() + print delta self.assertEqual(True, "users.007.roles.666" in delta[0]) + self.assertEqual(True, "users.007.rolist" in delta[0]) + self.assertEqual(True, "users.007.info" in delta[0]) self.assertEqual('superadmin', delta[0]["users.007.roles.666"]["type"]) + self.assertEqual('oops', delta[0]["users.007.rolist"][0]["type"]) + self.assertEqual(uinfo.id, delta[0]["users.007.info"]) if __name__ == '__main__': unittest.main() From a4f2f811d3e383b6e58a2a2ba9a6506d3a0bf08e Mon Sep 17 00:00:00 2001 From: Eremeev Danil Date: Thu, 9 Apr 2015 09:47:38 +0500 Subject: [PATCH 4/4] removed forgotten print --- tests/document/delta.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/document/delta.py b/tests/document/delta.py index e5a81c06..de940577 100644 --- a/tests/document/delta.py +++ b/tests/document/delta.py @@ -858,7 +858,6 @@ class DeltaTest(unittest.TestCase): d.users["007"]["rolist"].append(EmbeddedRole(type="oops")) d.users["007"]["info"] = uinfo delta = d._delta() - print delta self.assertEqual(True, "users.007.roles.666" in delta[0]) self.assertEqual(True, "users.007.rolist" in delta[0]) self.assertEqual(True, "users.007.info" in delta[0])