mixin inheritance
This commit is contained in:
		| @@ -469,7 +469,22 @@ class DocumentMetaclass(type): | |||||||
|     """Metaclass for all documents. |     """Metaclass for all documents. | ||||||
|     """ |     """ | ||||||
|      |      | ||||||
|  |          | ||||||
|     def __new__(cls, name, bases, attrs): |     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__') |         metaclass = attrs.get('__metaclass__') | ||||||
|         super_new = super(DocumentMetaclass, cls).__new__ |         super_new = super(DocumentMetaclass, cls).__new__ | ||||||
|         if metaclass and issubclass(metaclass, DocumentMetaclass): |         if metaclass and issubclass(metaclass, DocumentMetaclass): | ||||||
| @@ -488,8 +503,7 @@ class DocumentMetaclass(type): | |||||||
|                 superclasses[base._class_name] = base |                 superclasses[base._class_name] = base | ||||||
|                 superclasses.update(base._superclasses) |                 superclasses.update(base._superclasses) | ||||||
|             else:  # Add any mixin fields |             else:  # Add any mixin fields | ||||||
|                 attrs.update(dict([(k, v) for k, v in base.__dict__.items() |                 attrs.update(_get_mixin_fields(base)) | ||||||
|                                     if issubclass(v.__class__, BaseField)])) |  | ||||||
|  |  | ||||||
|             if hasattr(base, '_meta') and not base._meta.get('abstract'): |             if hasattr(base, '_meta') and not base._meta.get('abstract'): | ||||||
|                 # Ensure that the Document class may be subclassed - |                 # Ensure that the Document class may be subclassed - | ||||||
|   | |||||||
| @@ -2175,6 +2175,30 @@ class DocumentTest(unittest.TestCase): | |||||||
|  |  | ||||||
|         Person.drop_collection() |         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): |     def test_save_reference(self): | ||||||
|         """Ensure that a document reference field may be saved in the database. |         """Ensure that a document reference field may be saved in the database. | ||||||
|         """ |         """ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user