Merge pull request #2426 from volfpeter/master
Fix LazyReferenceField dereferencing in embedded documents
This commit is contained in:
		| @@ -2570,6 +2570,7 @@ class LazyReferenceField(BaseField): | |||||||
|         if not isinstance(value, (DBRef, Document, EmbeddedDocument)): |         if not isinstance(value, (DBRef, Document, EmbeddedDocument)): | ||||||
|             collection = self.document_type._get_collection_name() |             collection = self.document_type._get_collection_name() | ||||||
|             value = DBRef(collection, self.document_type.id.to_python(value)) |             value = DBRef(collection, self.document_type.id.to_python(value)) | ||||||
|  |             value = self.build_lazyref(value) | ||||||
|         return value |         return value | ||||||
|  |  | ||||||
|     def validate(self, value): |     def validate(self, value): | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ import pytest | |||||||
|  |  | ||||||
| from mongoengine import * | from mongoengine import * | ||||||
| from mongoengine.base import LazyReference | from mongoengine.base import LazyReference | ||||||
|  | from mongoengine.context_managers import query_counter | ||||||
|  |  | ||||||
| from tests.utils import MongoDBTestCase | from tests.utils import MongoDBTestCase | ||||||
|  |  | ||||||
| @@ -330,6 +331,50 @@ class TestLazyReferenceField(MongoDBTestCase): | |||||||
|         occ.in_embedded.in_list = [animal1.id, animal2.id] |         occ.in_embedded.in_list = [animal1.id, animal2.id] | ||||||
|         check_fields_type(occ) |         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): | ||||||
|  |                 ref["author"].name | ||||||
|  |             assert isinstance(ref.author, LazyReference) | ||||||
|  |             assert isinstance(ref.author.id, ObjectId) | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestGenericLazyReferenceField(MongoDBTestCase): | class TestGenericLazyReferenceField(MongoDBTestCase): | ||||||
|     def test_generic_lazy_reference_simple(self): |     def test_generic_lazy_reference_simple(self): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user