From e6317776c19fc93dcf43afe05db55b6fa78d7c30 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Tue, 19 Jun 2012 16:45:23 +0100 Subject: [PATCH] Fixes DBRef handling in _delta refs: hmarr/mongoengine#518 --- docs/changelog.rst | 4 ++++ mongoengine/base.py | 9 +++++++-- mongoengine/document.py | 3 ++- tests/test_document.py | 42 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index de84e97d..7e38eae4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,6 +2,10 @@ Changelog ========= +Changes in 0.6.X +================ +- Fixes error with _delta handling DBRefs + Changes in 0.6.11 ================== - Fixed inconsistency handling None values field attrs diff --git a/mongoengine/base.py b/mongoengine/base.py index 97ba76b9..a4c1599c 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -1043,11 +1043,16 @@ Invalid data to create a `%s` instance.\n%s""".strip() % (cls._class_name, error for path in set_fields: parts = path.split('.') d = doc + new_path = [] for p in parts: - if p.isdigit(): + if isinstance(d, DBRef): + break + elif p.isdigit(): d = d[int(p)] - else: + elif hasattr(d, 'get'): d = d.get(p) + new_path.append(p) + path = '.'.join(new_path) set_data[path] = d else: set_data = doc diff --git a/mongoengine/document.py b/mongoengine/document.py index a6bbb88c..ff9622aa 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -226,7 +226,7 @@ class Document(BaseDocument): if cascade_kwargs: # Allow granular control over cascades kwargs.update(cascade_kwargs) kwargs['_refs'] = _refs - self._changed_fields = [] + #self._changed_fields = [] self.cascade_save(**kwargs) except pymongo.errors.OperationFailure, err: @@ -246,6 +246,7 @@ class Document(BaseDocument): """Recursively saves any references / generic references on an object""" from fields import ReferenceField, GenericReferenceField _refs = kwargs.get('_refs', []) or [] + for name, cls in self._fields.items(): if not isinstance(cls, (ReferenceField, GenericReferenceField)): continue diff --git a/tests/test_document.py b/tests/test_document.py index 6f942f67..2b10c172 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -1667,6 +1667,48 @@ class DocumentTest(unittest.TestCase): self.assertEquals(p.owns[0], o) self.assertEquals(o.owner, p) + def test_circular_reference_deltas_2(self): + + class Person( Document ): + name = StringField() + owns = ListField( ReferenceField( 'Organization' ) ) + employer = ReferenceField( 'Organization' ) + + class Organization( Document ): + name = StringField() + owner = ReferenceField( 'Person' ) + employees = ListField( ReferenceField( 'Person' ) ) + + Person.drop_collection() + Organization.drop_collection() + + person = Person( name="owner" ) + person.save() + + employee = Person( name="employee" ) + employee.save() + + organization = Organization( name="company" ) + organization.save() + + person.owns.append( organization ) + organization.owner = person + + organization.employees.append( employee ) + employee.employer = organization + + person.save() + organization.save() + employee.save() + + p = Person.objects.get(name="owner") + e = Person.objects.get(name="employee") + o = Organization.objects.first() + + self.assertEquals(p.owns[0], o) + self.assertEquals(o.owner, p) + self.assertEquals(e.employer, o) + def test_delta(self): class Doc(Document):