Skip to content

Commit

Permalink
Merge pull request #2413 from bagerard/dynamic_document_parsing_known…
Browse files Browse the repository at this point in the history
…_fields

Bug fix in DynamicDocument which is not parsing known fields
  • Loading branch information
bagerard committed Nov 8, 2020
2 parents 161493c + 03af784 commit eb56fb9
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 14 additions & 17 deletions mongoengine/base/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,25 +111,22 @@ def __init__(self, *args, **values):
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_<field>_display methods
Expand Down
13 changes: 13 additions & 0 deletions tests/document/test_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ def test_simple_dynamic_document(self):
# 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()
Expand Down

0 comments on commit eb56fb9

Please sign in to comment.