diff --git a/docs/changelog.rst b/docs/changelog.rst index 3a9cbd5f..088aeba8 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,7 @@ Changelog Development =========== - (Fill this out as you fix issues and develop your features). +- Bug fix in DynamicDocument which isn not parsing known fields in constructor like Document do #2412 - When using pymongo >= 3.7, make use of Collection.count_documents instead of Collection.count and Cursor.count that got deprecated in pymongo >= 3.7. This should have a negative impact on performance of count see Issue #2219 diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 5b727437..ee88e894 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -111,25 +111,22 @@ class BaseDocument: if "_cls" not in values: self._cls = self._class_name - # Set passed values after initialisation - if self._dynamic: - dynamic_data = {} - for key, value in values.items(): - if key in self._fields or key == "_id": - setattr(self, key, value) - else: + # Set actual values + dynamic_data = {} + FileField = _import_class("FileField") + for key, value in values.items(): + key = self._reverse_db_field_map.get(key, key) + field = self._fields.get(key) + if field or key in ("id", "pk", "_cls"): + if __auto_convert and value is not None: + if field and not isinstance(field, FileField): + value = field.to_python(value) + setattr(self, key, value) + else: + if self._dynamic: dynamic_data[key] = value - else: - FileField = _import_class("FileField") - for key, value in values.items(): - key = self._reverse_db_field_map.get(key, key) - if key in self._fields or key in ("id", "pk", "_cls"): - if __auto_convert and value is not None: - field = self._fields.get(key) - if field and not isinstance(field, FileField): - value = field.to_python(value) - setattr(self, key, value) else: + # For strict Document self._data[key] = value # Set any get__display methods diff --git a/tests/document/test_dynamic.py b/tests/document/test_dynamic.py index 0032dfd9..dc7ecb8b 100644 --- a/tests/document/test_dynamic.py +++ b/tests/document/test_dynamic.py @@ -37,6 +37,19 @@ class TestDynamicDocument(MongoDBTestCase): # Confirm no changes to self.Person assert not hasattr(self.Person, "age") + def test_dynamic_document_parse_values_in_constructor_like_document_do(self): + class ProductDynamicDocument(DynamicDocument): + title = StringField() + price = FloatField() + + class ProductDocument(Document): + title = StringField() + price = FloatField() + + product = ProductDocument(title="Blabla", price="12.5") + dyn_product = ProductDynamicDocument(title="Blabla", price="12.5") + assert product.price == dyn_product.price == 12.5 + def test_change_scope_of_variable(self): """Test changing the scope of a dynamic field has no adverse effects""" p = self.Person()