From dc7b96a5691335e970b13fb30ef62426b126e2bd Mon Sep 17 00:00:00 2001 From: Eric Timmons Date: Wed, 16 Oct 2019 09:50:47 -0400 Subject: [PATCH] Make python value for LazyReferenceFields be a DBRef Previously, when reading a LazyReferenceField from the DB, it was stored internally in the parent document's _data field as an ObjectId. However, this meant that equality tests using an enclosing EmbeddedDocument would not return True when the EmbeddedDocument being compared to contained a DBRef or Document in _data. Enclosing Documents were largely unaffected because they look at the primary key for equality (which EmbeddedDocuments lack). This makes the internal Python representation of a LazyReferenceField (before the LazyReference itself has been constructed) a DBRef, using code identical to ReferenceField. --- mongoengine/fields.py | 9 +++++++++ tests/document/test_instance.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index f8f527a3..0c29d1bc 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -2502,6 +2502,15 @@ class LazyReferenceField(BaseField): else: return pk + def to_python(self, value): + """Convert a MongoDB-compatible type to a Python type.""" + if not self.dbref and not isinstance( + value, (DBRef, Document, EmbeddedDocument) + ): + collection = self.document_type._get_collection_name() + value = DBRef(collection, self.document_type.id.to_python(value)) + return value + def validate(self, value): if isinstance(value, LazyReference): if value.collection != self.document_type._get_collection_name(): diff --git a/tests/document/test_instance.py b/tests/document/test_instance.py index 6ba6827e..07376b4b 100644 --- a/tests/document/test_instance.py +++ b/tests/document/test_instance.py @@ -3321,7 +3321,7 @@ class TestInstance(MongoDBTestCase): def test_embedded_document_equality_with_lazy_ref(self): class Job(EmbeddedDocument): - boss = LazyReferenceField('Person') + boss = LazyReferenceField("Person") class Person(Document): job = EmbeddedDocumentField(Job)