diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 8915d801..db292ba9 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -2570,6 +2570,7 @@ class LazyReferenceField(BaseField): if not isinstance(value, (DBRef, Document, EmbeddedDocument)): collection = self.document_type._get_collection_name() value = DBRef(collection, self.document_type.id.to_python(value)) + value = self.build_lazyref(value) return value def validate(self, value): diff --git a/tests/fields/test_lazy_reference_field.py b/tests/fields/test_lazy_reference_field.py index 07d4d3a9..004f5272 100644 --- a/tests/fields/test_lazy_reference_field.py +++ b/tests/fields/test_lazy_reference_field.py @@ -3,6 +3,7 @@ import pytest from mongoengine import * from mongoengine.base import LazyReference +from mongoengine.context_managers import query_counter from tests.utils import MongoDBTestCase @@ -330,6 +331,50 @@ class TestLazyReferenceField(MongoDBTestCase): occ.in_embedded.in_list = [animal1.id, animal2.id] check_fields_type(occ) + def test_lazy_reference_embedded_dereferencing(self): + # Test case for #2375 + + # -- Test documents + + class Author(Document): + name = StringField() + + class AuthorReference(EmbeddedDocument): + author = LazyReferenceField(Author) + + class Book(Document): + authors = EmbeddedDocumentListField(AuthorReference) + + # -- Cleanup + + Author.drop_collection() + Book.drop_collection() + + # -- Create test data + + author_1 = Author(name="A1").save() + author_2 = Author(name="A2").save() + author_3 = Author(name="A3").save() + book = Book( + authors=[ + AuthorReference(author=author_1), + AuthorReference(author=author_2), + AuthorReference(author=author_3), + ] + ).save() + + with query_counter() as qc: + book = Book.objects.first() + # Accessing the list must not trigger dereferencing. + book.authors + assert qc == 1 + + for ref in book.authors: + with pytest.raises(AttributeError): + x = ref["author"].name + assert isinstance(ref.author, LazyReference) + assert isinstance(ref.author.id, ObjectId) + class TestGenericLazyReferenceField(MongoDBTestCase): def test_generic_lazy_reference_simple(self):