From be8f1b9fdd522888527f871c1fbc2a0f6f0af279 Mon Sep 17 00:00:00 2001 From: Erdenezul Batmunkh Date: Thu, 14 Sep 2017 22:24:27 +0900 Subject: [PATCH 1/2] add failing test for generic_emdedded_document query #1651 --- tests/queryset/queryset.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py index c78ed985..4bc5fef6 100644 --- a/tests/queryset/queryset.py +++ b/tests/queryset/queryset.py @@ -4790,6 +4790,30 @@ class QuerySetTest(unittest.TestCase): for obj in C.objects.no_sub_classes(): self.assertEqual(obj.__class__, C) + def test_query_generic_embedded_document(self): + """Ensure that querying sub field on generic_embedded_field works + """ + class A(EmbeddedDocument): + a_name = StringField() + + class B(EmbeddedDocument): + b_name = StringField() + + class Doc(Document): + document = GenericEmbeddedDocumentField(choices=(A, B)) + + Doc.drop_collection() + Doc(document=A(a_name='A doc')).save() + Doc(document=B(b_name='B doc')).save() + + # Using raw in filter working fine + self.assertEqual(Doc.objects( + __raw__={'document.a_name': 'A doc'}).count(), 1) + self.assertEqual(Doc.objects( + __raw__={'document.b_name': 'B doc'}).count(), 1) + self.assertEqual(Doc.objects(document__a_name='A doc').count(), 1) + self.assertEqual(Doc.objects(document__b_name='B doc').count(), 1) + def test_query_reference_to_custom_pk_doc(self): class A(Document): From aa4996ef28bec2614cb11c055b5d184fee6b9549 Mon Sep 17 00:00:00 2001 From: Erdenezul Date: Fri, 15 Sep 2017 11:18:24 +0800 Subject: [PATCH 2/2] fix bug query subfield in generic_embedded_document #1651 --- mongoengine/fields.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index fffba7ac..cc66008b 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -692,6 +692,14 @@ class GenericEmbeddedDocumentField(BaseField): value.validate(clean=clean) + def lookup_member(self, member_name): + if self.choices: + for choice in self.choices: + field = choice._fields.get(member_name) + if field: + return field + return None + def to_mongo(self, document, use_db_field=True, fields=None): if document is None: return None