diff --git a/docs/changelog.rst b/docs/changelog.rst index ffbc8c54..42d98597 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -19,6 +19,7 @@ Changes in 0.9.X - DEV - Added __ support to escape field name in fields lookup keywords that match operators names #949 - Support for PyMongo 3+ #946 - Fix for issue where FileField deletion did not free space in GridFS. +- No_dereference() not respected on embedded docs containing reference. #517 Changes in 0.9.0 ================ diff --git a/mongoengine/base/fields.py b/mongoengine/base/fields.py index 91f95b4f..b3ec0763 100644 --- a/mongoengine/base/fields.py +++ b/mongoengine/base/fields.py @@ -290,6 +290,7 @@ class ComplexBaseField(BaseField): return value if self.field: + self.field._auto_dereference = self._auto_dereference value_dict = dict([(key, self.field.to_python(item)) for key, item in value.items()]) else: diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 53d4ac95..9176828c 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -546,7 +546,7 @@ class EmbeddedDocumentField(BaseField): def to_python(self, value): if not isinstance(value, self.document_type): - return self.document_type._from_son(value) + return self.document_type._from_son(value, _auto_dereference=self._auto_dereference) return value def to_mongo(self, value, use_db_field=True, fields=[]): diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py index 65d84305..3dc3ef20 100644 --- a/tests/queryset/queryset.py +++ b/tests/queryset/queryset.py @@ -13,7 +13,7 @@ import pymongo from pymongo.errors import ConfigurationError from pymongo.read_preferences import ReadPreference -from bson import ObjectId +from bson import ObjectId, DBRef from mongoengine import * from mongoengine.connection import get_connection, get_db @@ -4185,6 +4185,41 @@ class QuerySetTest(unittest.TestCase): Organization)) self.assertTrue(isinstance(qs.first().organization, Organization)) + def test_no_dereference_embedded_doc(self): + + class User(Document): + name = StringField() + + class Member(EmbeddedDocument): + name = StringField() + user = ReferenceField(User) + + class Organization(Document): + name = StringField() + members = ListField(EmbeddedDocumentField(Member)) + ceo = ReferenceField(User) + member = EmbeddedDocumentField(Member) + admin = ListField(ReferenceField(User)) + + Organization.drop_collection() + User.drop_collection() + + user = User(name="Flash") + user.save() + + member = Member(name="Flash", user=user) + + company = Organization(name="Mongo Inc", ceo=user, member=member) + company.admin.append(user) + company.members.append(member) + company.save() + + result = Organization.objects().no_dereference().first() + + self.assertTrue(isinstance(result.admin[0], (DBRef, ObjectId))) + self.assertTrue(isinstance(result.member.user, (DBRef, ObjectId))) + self.assertTrue(isinstance(result.members[0].user, (DBRef, ObjectId))) + def test_cached_queryset(self): class Person(Document): name = StringField()