Skip to content

Commit 4fee413

Browse files
committed
add support for direct field queries
1 parent f109cf5 commit 4fee413

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

django_mongodb_backend/fields/embedded_model_array.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import difflib
22

33
from django.core.exceptions import FieldDoesNotExist
4+
from django.db import models
5+
from django.db.models.expressions import Col
46
from django.db.models.lookups import Transform
57

68
from ..forms import EmbeddedModelArrayFormField
79
from ..query_utils import process_lhs, process_rhs
810
from . import EmbeddedModelField
911
from .array import ArrayField
1012
from .embedded_model import EMFExact
11-
from .json import build_json_mql_path
1213

1314

1415
class EmbeddedModelArrayField(ArrayField):
@@ -55,18 +56,29 @@ def get_transform(self, name):
5556
@EmbeddedModelArrayField.register_lookup
5657
class EMFArrayExact(EMFExact):
5758
def as_mql(self, compiler, connection):
58-
mql, key_transforms, json_key_transforms = self.lhs.preprocess_lhs(compiler, connection)
59-
# TODO, maybe a new flow of transform query must be build
60-
# this part must merge the two part of the transform train.
59+
lhs_mql = process_lhs(self, compiler, connection)
6160
value = process_rhs(self, compiler, connection)
62-
transforms = build_json_mql_path("$$this", key_transforms)
63-
return {
64-
"$reduce": {
65-
"input": mql,
66-
"initialValue": False,
67-
"in": {"$or": ["$$value", {"$eq": [f"$$this.{transforms}", value]}]},
61+
if isinstance(self.lhs, Col | KeyTransform):
62+
if isinstance(value, models.Model):
63+
value, emf_data = self.model_to_dict(value)
64+
# Get conditions for any nested EmbeddedModelFields.
65+
conditions = self.get_conditions({"$$item": (value, emf_data)})
66+
return {
67+
"$anyElementTrue": {
68+
"$map": {"input": lhs_mql, "as": "item", "in": {"$and": conditions}}
69+
}
70+
}
71+
lhs_mql = process_lhs(self.lhs, compiler, connection)
72+
return {
73+
"$anyElementTrue": {
74+
"$map": {
75+
"input": lhs_mql,
76+
"as": "item",
77+
"in": {"$eq": [f"$$item.{self.lhs.key_name}", value]},
78+
}
79+
}
6880
}
69-
}
81+
return connection.mongo_operators[self.lookup_name](lhs_mql, value)
7082

7183

7284
class KeyTransform(Transform):
@@ -77,7 +89,7 @@ def __init__(self, key_name, ref_field, *args, **kwargs):
7789
self.ref_field = ref_field
7890

7991
def get_lookup(self, name):
80-
return self.ref_field.get_lookup(name)
92+
return self.output_field.get_lookup(name)
8193

8294
def get_transform(self, name):
8395
"""
@@ -99,11 +111,12 @@ def get_transform(self, name):
99111
)
100112

101113
def as_mql(self, compiler, connection):
102-
return process_lhs(self, compiler, connection)
114+
lhs_mql = process_lhs(self, compiler, connection)
115+
return f"{lhs_mql}.{self.key_name}"
103116

104117
@property
105118
def output_field(self):
106-
return self.ref_field
119+
return EmbeddedModelArrayField(self.ref_field)
107120

108121

109122
class KeyTransformFactory:

tests/model_fields_/test_embedded_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def test_filter_with_field(self):
206206
def test_filter_with_model(self):
207207
self.assertCountEqual(
208208
Movie.objects.filter(reviews=Review(title="Horrible", rating=2)),
209-
[self.clouds, self.frozen],
209+
[self.frozen],
210210
)
211211

212212
def test_filter_with_embeddedfield_path(self):

0 commit comments

Comments
 (0)