Merge pull request #976 from seglberg/bugfix/#954-ref-field-subclass

Reflect Inheritance in Field's 'owner_document'
This commit is contained in:
Matthew Ellison 2015-04-30 09:22:15 -04:00
commit 06e4ed1bb4
3 changed files with 61 additions and 6 deletions

View File

@ -83,6 +83,7 @@ class BaseField(object):
self.help_text = help_text
self.null = null
self.sparse = sparse
self._owner_document = None
# Adjust the appropriate creation counter, and save our local copy.
if self.db_field == '_id':
@ -189,6 +190,17 @@ class BaseField(object):
self.validate(value, **kwargs)
@property
def owner_document(self):
return self._owner_document
def _set_owner_document(self, owner_document):
self._owner_document = owner_document
@owner_document.setter
def owner_document(self, owner_document):
self._set_owner_document(owner_document)
class ComplexBaseField(BaseField):
@ -398,11 +410,6 @@ class ComplexBaseField(BaseField):
self.field.owner_document = owner_document
self._owner_document = owner_document
def _get_owner_document(self, owner_document):
self._owner_document = owner_document
owner_document = property(_get_owner_document, _set_owner_document)
class ObjectIdField(BaseField):

View File

@ -176,7 +176,8 @@ class DocumentMetaclass(type):
# Handle delete rules
for field in new_class._fields.itervalues():
f = field
f.owner_document = new_class
if f.owner_document is None:
f.owner_document = new_class
delete_rule = getattr(f, 'reverse_delete_rule', DO_NOTHING)
if isinstance(f, CachedReferenceField):

View File

@ -165,6 +165,53 @@ class ValidatorErrorTest(unittest.TestCase):
self.assertRaises(ValidationError, lambda: d2.validate())
def test_parent_reference_in_child_document(self):
"""
Test to ensure a ReferenceField can store a reference to a parent
class when inherited. Issue #954.
"""
class Parent(Document):
meta = {'allow_inheritance': True}
reference = ReferenceField('self')
class Child(Parent):
pass
parent = Parent()
parent.save()
child = Child(reference=parent)
# Saving child should not raise a ValidationError
try:
child.save()
except ValidationError as e:
self.fail("ValidationError raised: %s" % e.message)
def test_parent_reference_set_as_attribute_in_child_document(self):
"""
Test to ensure a ReferenceField can store a reference to a parent
class when inherited and when set via attribute. Issue #954.
"""
class Parent(Document):
meta = {'allow_inheritance': True}
reference = ReferenceField('self')
class Child(Parent):
pass
parent = Parent()
parent.save()
child = Child()
child.reference = parent
# Saving the child should not raise a ValidationError
try:
child.save()
except ValidationError as e:
self.fail("ValidationError raised: %s" % e.message)
if __name__ == '__main__':
unittest.main()