diff --git a/mongoengine/base/metaclasses.py b/mongoengine/base/metaclasses.py index 8a25ff3d..6fdbe19c 100644 --- a/mongoengine/base/metaclasses.py +++ b/mongoengine/base/metaclasses.py @@ -390,10 +390,16 @@ class TopLevelDocumentMetaclass(DocumentMetaclass): new_class._fields['id'] = ObjectIdField(db_field='_id') new_class._fields['id'].name = 'id' new_class.id = new_class._fields['id'] - - # Prepend id field to _fields_ordered - if 'id' in new_class._fields and 'id' not in new_class._fields_ordered: - new_class._fields_ordered = ('id', ) + new_class._fields_ordered + new_class._db_field_map['id'] = '_id' + new_class._reverse_db_field_map['_id'] = 'id' + if 'id' in new_class._fields_ordered: + # An existing id field will be overwritten anyway, so remove it + loc = new_class._fields_ordered.index('id') + new_class._fields_ordered = new_class._fields_ordered[:loc] + \ + new_class._fields_ordered[loc+1:] + else: + # Prepend id field to _fields_ordered + new_class._fields_ordered = ('id', ) + new_class._fields_ordered # Merge in exceptions with parent hierarchy exceptions_to_merge = (DoesNotExist, MultipleObjectsReturned) diff --git a/tests/document/inheritance.py b/tests/document/inheritance.py index afa3ccea..e408e611 100644 --- a/tests/document/inheritance.py +++ b/tests/document/inheritance.py @@ -307,6 +307,23 @@ class InheritanceTest(unittest.TestCase): doc = Animal(name='dog') self.assertFalse('_cls' in doc.to_mongo()) + def test_abstract_handle_ids_in_metaclass_properly(self): + + class City(Document): + continent = StringField() + meta = {'abstract': True, + 'allow_inheritance': False} + + class EuropeanCity(City): + name = StringField() + country = StringField() + + berlin = EuropeanCity(name='Berlin', continent='Europe') + self.assertEqual(len(berlin._db_field_map), len(berlin._fields_ordered)) + self.assertEqual(len(berlin._reverse_db_field_map), len(berlin._fields_ordered)) + self.assertEqual(len(berlin._fields_ordered), 4) + self.assertEqual(berlin._fields_ordered[0], 'id') + def test_abstract_document_creation_does_not_fail(self): class City(Document):