mongoengine
mongoengine copied to clipboard
DictField _auto_dereference gets changed after first query
The _auto_dereference flag of DictField defaults to False, but it gets overwritten to True (permanently) after any Doc gets loading through a Queryset
def test_dictfield_dump_document_with_inheritance__cls(self):
"""Ensure a DictField can handle another document's dump."""
class Doc(Document):
field = DictField()
class ToEmbedParent(Document):
id = IntField(primary_key=True)
recursive = DictField()
meta = {"allow_inheritance": True}
class ToEmbedChild(ToEmbedParent):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Doc.drop_collection()
ToEmbedParent.drop_collection()
# with a Document with a _cls field
to_embed_recursive = ToEmbedChild(id=1).save()
to_embed_child = ToEmbedChild(
id=2, recursive=to_embed_recursive.to_mongo().to_dict()
).save()
doc_dump_as_dict = to_embed_child.to_mongo().to_dict()
doc = Doc(field=doc_dump_as_dict)
assert Doc.field._auto_dereference is False
assert isinstance(doc.field, dict) # depends on auto_dereference
doc.save()
assert isinstance(doc.field, dict)
expected = {
"_id": 2,
"_cls": "ToEmbedParent.ToEmbedChild",
"recursive": {
"_id": 1,
"_cls": "ToEmbedParent.ToEmbedChild",
"recursive": {},
},
}
assert doc.field == expected
# Now after querying
_ = Doc.objects.first()
assert Doc.field._auto_dereference is False # Fails
doc = Doc(field=doc_dump_as_dict)
assert isinstance(doc.field, dict) # Fails
This has consequence on how it loads an EmbeddedDocument with inheritance afterward. It is due to this part , which mutates the original field's auto_deref flag for DictField (not only in case of copies of the Fields as it should)