diff --git a/mongoengine/fields.py b/mongoengine/fields.py index b05e726a..8fdeae15 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..f5d248af 100644 --- a/tests/queryset/test_transform.py +++ b/tests/queryset/test_transform.py @@ -344,6 +344,31 @@ 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()