Skip to content

Commit 903982e

Browse files
committed
Merge pull request #1088 from touilleMan/bug-1058
Fix DictField with '_cls' field is converted to Document on access
2 parents 92b9cb5 + 736fe5b commit 903982e

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

mongoengine/fields.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ class DictField(ComplexBaseField):
794794

795795
def __init__(self, basecls=None, field=None, *args, **kwargs):
796796
self.field = field
797+
self._auto_dereference = False
797798
self.basecls = basecls or BaseField
798799
if not issubclass(self.basecls, BaseField):
799800
self.error('DictField only accepts dict values')

tests/fields/fields.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,44 @@ class BlogPost(Document):
12571257

12581258
BlogPost.drop_collection()
12591259

1260+
def test_dictfield_dump_document(self):
1261+
"""Ensure a DictField can handle another document's dump
1262+
"""
1263+
class Doc(Document):
1264+
field = DictField()
1265+
1266+
class ToEmbed(Document):
1267+
id = IntField(primary_key=True, default=1)
1268+
recursive = DictField()
1269+
1270+
class ToEmbedParent(Document):
1271+
id = IntField(primary_key=True, default=1)
1272+
recursive = DictField()
1273+
1274+
meta = {'allow_inheritance': True}
1275+
1276+
class ToEmbedChild(ToEmbedParent):
1277+
pass
1278+
1279+
to_embed_recursive = ToEmbed(id=1).save()
1280+
to_embed = ToEmbed(
1281+
id=2, recursive=to_embed_recursive.to_mongo().to_dict()).save()
1282+
doc = Doc(field=to_embed.to_mongo().to_dict())
1283+
doc.save()
1284+
assert isinstance(doc.field, dict)
1285+
assert doc.field == {'_id': 2, 'recursive': {'_id': 1, 'recursive': {}}}
1286+
# Same thing with a Document with a _cls field
1287+
to_embed_recursive = ToEmbedChild(id=1).save()
1288+
to_embed_child = ToEmbedChild(
1289+
id=2, recursive=to_embed_recursive.to_mongo().to_dict()).save()
1290+
doc = Doc(field=to_embed_child.to_mongo().to_dict())
1291+
doc.save()
1292+
assert isinstance(doc.field, dict)
1293+
assert doc.field == {
1294+
'_id': 2, '_cls': 'ToEmbedParent.ToEmbedChild',
1295+
'recursive': {'_id': 1, '_cls': 'ToEmbedParent.ToEmbedChild', 'recursive': {}}
1296+
}
1297+
12601298
def test_dictfield_strict(self):
12611299
"""Ensure that dict field handles validation if provided a strict field type."""
12621300

@@ -3327,6 +3365,39 @@ class Doc(Document):
33273365
doc = Doc.objects.get()
33283366
self.assertEqual(doc.embed_me.field_1, "hello")
33293367

3368+
def test_dynamicfield_dump_document(self):
3369+
"""Ensure a DynamicField can handle another document's dump
3370+
"""
3371+
class Doc(Document):
3372+
field = DynamicField()
3373+
3374+
class ToEmbed(Document):
3375+
id = IntField(primary_key=True, default=1)
3376+
recursive = DynamicField()
3377+
3378+
class ToEmbedParent(Document):
3379+
id = IntField(primary_key=True, default=1)
3380+
recursive = DynamicField()
3381+
3382+
meta = {'allow_inheritance': True}
3383+
3384+
class ToEmbedChild(ToEmbedParent):
3385+
pass
3386+
3387+
to_embed_recursive = ToEmbed(id=1).save()
3388+
to_embed = ToEmbed(id=2, recursive=to_embed_recursive).save()
3389+
doc = Doc(field=to_embed)
3390+
doc.save()
3391+
assert isinstance(doc.field, ToEmbed)
3392+
assert doc.field == to_embed
3393+
# Same thing with a Document with a _cls field
3394+
to_embed_recursive = ToEmbedChild(id=1).save()
3395+
to_embed_child = ToEmbedChild(id=2, recursive=to_embed_recursive).save()
3396+
doc = Doc(field=to_embed_child)
3397+
doc.save()
3398+
assert isinstance(doc.field, ToEmbedChild)
3399+
assert doc.field == to_embed_child
3400+
33303401
def test_invalid_dict_value(self):
33313402
class DictFieldTest(Document):
33323403
dictionary = DictField(required=True)

0 commit comments

Comments
 (0)