Embedded Documents still can inherit fields MongoEngine/mongoengine#84

This commit is contained in:
Ross Lawley 2012-08-22 09:27:18 +01:00
parent bb1b9bc1d3
commit 0526f577ff
2 changed files with 29 additions and 8 deletions

View File

@ -514,6 +514,18 @@ class DocumentMetaclass(type):
if hasattr(base, '_fields'): if hasattr(base, '_fields'):
doc_fields.update(base._fields) doc_fields.update(base._fields)
# Standard object mixin - merge in any Fields
if not hasattr(base, '_meta'):
base_fields = {}
for attr_name, attr_value in base.__dict__.iteritems():
if not isinstance(attr_value, BaseField):
continue
attr_value.name = attr_name
if not attr_value.db_field:
attr_value.db_field = attr_name
base_fields[attr_name] = attr_value
doc_fields.update(base_fields)
# Discover any document fields # Discover any document fields
field_names = {} field_names = {}
for attr_name, attr_value in attrs.iteritems(): for attr_name, attr_value in attrs.iteritems():
@ -537,9 +549,8 @@ class DocumentMetaclass(type):
# Set _fields and db_field maps # Set _fields and db_field maps
attrs['_fields'] = doc_fields attrs['_fields'] = doc_fields
attrs['_db_field_map'] = dict( attrs['_db_field_map'] = dict([(k, getattr(v, 'db_field', k))
((k, v.db_field) for k, v in doc_fields.items() for k, v in doc_fields.iteritems()])
if k != v.db_field))
attrs['_reverse_db_field_map'] = dict( attrs['_reverse_db_field_map'] = dict(
(v, k) for k, v in attrs['_db_field_map'].iteritems()) (v, k) for k, v in attrs['_db_field_map'].iteritems())
@ -757,11 +768,6 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
if callable(collection): if callable(collection):
meta['collection'] = collection(base) meta['collection'] = collection(base)
# Standard object mixin - merge in any Fields
if not hasattr(base, '_meta'):
attrs.update(dict([(k, v) for k, v in base.__dict__.items()
if issubclass(v.__class__, BaseField)]))
meta.merge(attrs.get('_meta', {})) # Top level meta meta.merge(attrs.get('_meta', {})) # Top level meta
# Only simple classes (direct subclasses of Document) # Only simple classes (direct subclasses of Document)

View File

@ -2585,6 +2585,21 @@ class DocumentTest(unittest.TestCase):
Person.drop_collection() Person.drop_collection()
def test_object_mixins(self):
class NameMixin(object):
name = StringField()
class Foo(EmbeddedDocument, NameMixin):
quantity = IntField()
self.assertEqual(['name', 'quantity'], sorted(Foo._fields.keys()))
class Bar(Document, NameMixin):
widgets = StringField()
self.assertEqual(['id', 'name', 'widgets'], sorted(Bar._fields.keys()))
def test_mixin_inheritance(self): def test_mixin_inheritance(self):
class BaseMixIn(object): class BaseMixIn(object):
count = IntField() count = IntField()