diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 9d366706..ce96837a 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -684,8 +684,13 @@ class BaseDocument(object): # class if unavailable class_name = son.get('_cls', cls._class_name) - # Convert SON to a dict, making sure each key is a string - data = {str(key): value for key, value in son.iteritems()} + # Convert SON to a data dict, making sure each key is a string and + # corresponds to the right db field. + data = {} + for key, value in son.iteritems(): + key = str(key) + key = cls._db_field_map.get(key, key) + data[key] = value # Return correct subclass for document type if class_name != cls._class_name: diff --git a/tests/fields/fields.py b/tests/fields/fields.py index ed7baa2b..7e4ec601 100644 --- a/tests/fields/fields.py +++ b/tests/fields/fields.py @@ -1883,6 +1883,29 @@ class FieldTest(MongoDBTestCase): doc = self.db.test.find_one() self.assertEqual(doc['x']['i'], 2) + def test_double_embedded_db_field(self): + """Make sure that multiple layers of embedded fields resolve db + fields properly and can be initialized using dicts. + """ + class C(EmbeddedDocument): + txt = StringField() + + class B(EmbeddedDocument): + c = EmbeddedDocumentField(C, db_field='fc') + + class A(Document): + b = EmbeddedDocumentField(B, db_field='fb') + + a = A( + b=B( + c=C(txt='hi') + ) + ) + a.validate() + + a = A(b={'c': {'txt': 'hi'}}) + a.validate() + def test_embedded_document_validation(self): """Ensure that invalid embedded documents cannot be assigned to embedded document fields.