diff --git a/mongoengine/fields.py b/mongoengine/fields.py index b05e726a..f50e6045 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -773,6 +773,9 @@ class EmbeddedDocumentField(BaseField): def prepare_query_value(self, op, value): if value is not None and not isinstance(value, self.document_type): + # Short circuit for special operators, returning them as is + if isinstance(value, dict) and all(k.startswith('$') for k in value.keys()): + return value try: value = self.document_type._from_son(value) except ValueError: diff --git a/tests/queryset/test_transform.py b/tests/queryset/test_transform.py index 8d6c2d06..0fba3975 100644 --- a/tests/queryset/test_transform.py +++ b/tests/queryset/test_transform.py @@ -344,6 +344,36 @@ class TestTransform(unittest.TestCase): ) assert update == {"$pull": {"content.text": {"word": {"$nin": ["foo", "bar"]}}}} + def test_transform_embedded_document_list_fields(self): + """ + Test added to check filtering + EmbeddedDocumentListField which is inside a EmbeddedDocumentField + """ + + class Drink(EmbeddedDocument): + id = StringField() + meta = { + 'strict': False + } + + class Shop(Document): + drinks = EmbeddedDocumentListField(Drink) + + Shop.drop_collection() + drinks = [Drink(id='drink_1'), Drink(id='drink_2')] + Shop.objects.create(drinks=drinks) + q_obj = transform.query( + Shop, + drinks__all=[{'$elemMatch': {'_id': x.id}} for x in drinks] + ) + assert q_obj == { + 'drinks': { + '$all': [{'$elemMatch': {'_id': x.id}} for x in drinks] + } + } + + Shop.drop_collection() + if __name__ == "__main__": unittest.main()