Fixes DBRef handling in _delta

refs: hmarr/mongoengine#518
This commit is contained in:
Ross Lawley 2012-06-19 16:45:23 +01:00
parent efeaba39a4
commit e6317776c1
4 changed files with 55 additions and 3 deletions

View File

@ -2,6 +2,10 @@
Changelog Changelog
========= =========
Changes in 0.6.X
================
- Fixes error with _delta handling DBRefs
Changes in 0.6.11 Changes in 0.6.11
================== ==================
- Fixed inconsistency handling None values field attrs - Fixed inconsistency handling None values field attrs

View File

@ -1043,11 +1043,16 @@ Invalid data to create a `%s` instance.\n%s""".strip() % (cls._class_name, error
for path in set_fields: for path in set_fields:
parts = path.split('.') parts = path.split('.')
d = doc d = doc
new_path = []
for p in parts: for p in parts:
if p.isdigit(): if isinstance(d, DBRef):
break
elif p.isdigit():
d = d[int(p)] d = d[int(p)]
else: elif hasattr(d, 'get'):
d = d.get(p) d = d.get(p)
new_path.append(p)
path = '.'.join(new_path)
set_data[path] = d set_data[path] = d
else: else:
set_data = doc set_data = doc

View File

@ -226,7 +226,7 @@ class Document(BaseDocument):
if cascade_kwargs: # Allow granular control over cascades if cascade_kwargs: # Allow granular control over cascades
kwargs.update(cascade_kwargs) kwargs.update(cascade_kwargs)
kwargs['_refs'] = _refs kwargs['_refs'] = _refs
self._changed_fields = [] #self._changed_fields = []
self.cascade_save(**kwargs) self.cascade_save(**kwargs)
except pymongo.errors.OperationFailure, err: except pymongo.errors.OperationFailure, err:
@ -246,6 +246,7 @@ class Document(BaseDocument):
"""Recursively saves any references / generic references on an object""" """Recursively saves any references / generic references on an object"""
from fields import ReferenceField, GenericReferenceField from fields import ReferenceField, GenericReferenceField
_refs = kwargs.get('_refs', []) or [] _refs = kwargs.get('_refs', []) or []
for name, cls in self._fields.items(): for name, cls in self._fields.items():
if not isinstance(cls, (ReferenceField, GenericReferenceField)): if not isinstance(cls, (ReferenceField, GenericReferenceField)):
continue continue

View File

@ -1667,6 +1667,48 @@ class DocumentTest(unittest.TestCase):
self.assertEquals(p.owns[0], o) self.assertEquals(p.owns[0], o)
self.assertEquals(o.owner, p) 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): def test_delta(self):
class Doc(Document): class Doc(Document):