Repository: MongoEngine/mongoengine

Issue:
document._cls field not set after document.save() call
```
from mongoengine import (
    connection,
    Document,
    EmbeddedDocument,
    EmbeddedDocumentField,
    StringField
    )

class EmbedData(EmbeddedDocument):
    data = StringField()
    meta = {'allow_inheritance': True}

class DataDoc(Document):
    name = StringField()
    embed = EmbeddedDocumentField(EmbedData)
    meta = {'allow_inheritance': True}

connection.connect(is_mock=True)
test_doc = DataDoc(name='test',embed=EmbedData(data='data'))
test_doc.save()
saved_doc = DataDoc.objects(name='test').first()
assert test_doc._cls == saved_doc._cls
assert test_doc.embed._cls == saved_doc.embed._cls
test_doc.delete()
```
In MongoEninge 0.15.3, the above code works, with version 0.16.0, the asserts fail due to the _cls field being set to None in the test_doc object.


Discussion:

Resolving patch:
diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py
--- a/mongoengine/base/document.py
+++ b/mongoengine/base/document.py
@@ -91,6 +91,9 @@ def __init__(self, *args, **values):
             value = getattr(self, key, None)
             setattr(self, key, value)
 
+        if '_cls' not in values:
+            self._cls = self._class_name
+
         # Set passed values after initialisation
         if self._dynamic:
             dynamic_data = {}


Test patch:
diff --git a/tests/document/inheritance.py b/tests/document/inheritance.py
--- a/tests/document/inheritance.py
+++ b/tests/document/inheritance.py
@@ -2,11 +2,11 @@
 import unittest
 import warnings
 
-from tests.fixtures import Base
-
-from mongoengine import Document, EmbeddedDocument, connect, ReferenceField,\
-    BooleanField, GenericReferenceField, IntField, StringField
+from mongoengine import (BooleanField, Document, EmbeddedDocument,
+                         EmbeddedDocumentField, GenericReferenceField,
+                         IntField, ReferenceField, StringField, connect)
 from mongoengine.connection import get_db
+from tests.fixtures import Base
 
 __all__ = ('InheritanceTest', )
 
@@ -23,6 +23,27 @@ def tearDown(self):
                 continue
             self.db.drop_collection(collection)
 
+    def test_constructor_cls(self):
+        # Ensures _cls is properly set during construction
+        # and when object gets reloaded (prevent regression of #1950)
+        class EmbedData(EmbeddedDocument):
+            data = StringField()
+            meta = {'allow_inheritance': True}
+
+        class DataDoc(Document):
+            name = StringField()
+            embed = EmbeddedDocumentField(EmbedData)
+            meta = {'allow_inheritance': True}
+
+        test_doc = DataDoc(name='test', embed=EmbedData(data='data'))
+        assert test_doc._cls == 'DataDoc'
+        assert test_doc.embed._cls == 'EmbedData'
+        test_doc.save()
+        saved_doc = DataDoc.objects.with_id(test_doc.id)
+        assert test_doc._cls == saved_doc._cls
+        assert test_doc.embed._cls == saved_doc.embed._cls
+        test_doc.delete()
+
     def test_superclasses(self):
         """Ensure that the correct list of superclasses is assembled.
         """