mixin inheritance

This commit is contained in:
Wilson Júnior 2011-12-19 11:31:42 -02:00
parent 6d9bfff19c
commit 0d867a108d
2 changed files with 41 additions and 3 deletions

View File

@ -468,8 +468,23 @@ class ObjectIdField(BaseField):
class DocumentMetaclass(type):
"""Metaclass for all documents.
"""
def __new__(cls, name, bases, attrs):
def _get_mixin_fields(base):
attrs = {}
attrs.update(dict([(k, v) for k, v in base.__dict__.items()
if issubclass(v.__class__, BaseField)]))
for p_base in base.__bases__:
#optimize :-)
if p_base in (object, BaseDocument):
continue
attrs.update(_get_mixin_fields(p_base))
return attrs
metaclass = attrs.get('__metaclass__')
super_new = super(DocumentMetaclass, cls).__new__
if metaclass and issubclass(metaclass, DocumentMetaclass):
@ -488,8 +503,7 @@ class DocumentMetaclass(type):
superclasses[base._class_name] = base
superclasses.update(base._superclasses)
else: # Add any mixin fields
attrs.update(dict([(k, v) for k, v in base.__dict__.items()
if issubclass(v.__class__, BaseField)]))
attrs.update(_get_mixin_fields(base))
if hasattr(base, '_meta') and not base._meta.get('abstract'):
# Ensure that the Document class may be subclassed -

View File

@ -2175,6 +2175,30 @@ class DocumentTest(unittest.TestCase):
Person.drop_collection()
def test_mixin_inheritance(self):
class BaseMixIn(object):
count = IntField()
data = StringField()
class DoubleMixIn(BaseMixIn):
comment = StringField()
class TestDoc(Document, DoubleMixIn):
age = IntField()
TestDoc.drop_collection()
t = TestDoc(count=12, data="test",
comment="great!", age=19)
t.save()
t = TestDoc.objects.first()
self.assertEquals(t.age, 19)
self.assertEquals(t.comment, "great!")
self.assertEquals(t.data, "test")
self.assertEquals(t.count, 12)
def test_save_reference(self):
"""Ensure that a document reference field may be saved in the database.
"""