Skip to content

Commit 8079b1b

Browse files
committed
add support for direct field queries
1 parent 8cc88f1 commit 8079b1b

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,15 +1,16 @@
11
import difflib
22

33
from django.core.exceptions import FieldDoesNotExist
4+
from django.db import models
45
from django.db.models import Field
6+
from django.db.models.expressions import Col
57
from django.db.models.lookups import Transform
68

79
from .. import forms
810
from ..query_utils import process_lhs, process_rhs
911
from . import EmbeddedModelField
1012
from .array import ArrayField
1113
from .embedded_model import EMFExact
12-
from .json import build_json_mql_path
1314

1415

1516
class EmbeddedModelArrayField(ArrayField):
@@ -66,18 +67,29 @@ def get_transform(self, name):
6667
@EmbeddedModelArrayField.register_lookup
6768
class EMFArrayExact(EMFExact):
6869
def as_mql(self, compiler, connection):
69-
mql, key_transforms, json_key_transforms = self.lhs.preprocess_lhs(compiler, connection)
70-
# TODO, maybe a new flow of transform query must be build
71-
# this part must merge the two part of the transform train.
70+
lhs_mql = process_lhs(self, compiler, connection)
7271
value = process_rhs(self, compiler, connection)
73-
transforms = build_json_mql_path("$$this", key_transforms)
74-
return {
75-
"$reduce": {
76-
"input": mql,
77-
"initialValue": False,
78-
"in": {"$or": ["$$value", {"$eq": [f"$$this.{transforms}", value]}]},
72+
if isinstance(self.lhs, Col | KeyTransform):
73+
if isinstance(value, models.Model):
74+
value, emf_data = self.model_to_dict(value)
75+
# Get conditions for any nested EmbeddedModelFields.
76+
conditions = self.get_conditions({"$$item": (value, emf_data)})
77+
return {
78+
"$anyElementTrue": {
79+
"$map": {"input": lhs_mql, "as": "item", "in": {"$and": conditions}}
80+
}
81+
}
82+
lhs_mql = process_lhs(self.lhs, compiler, connection)
83+
return {
84+
"$anyElementTrue": {
85+
"$map": {
86+
"input": lhs_mql,
87+
"as": "item",
88+
"in": {"$eq": [f"$$item.{self.lhs.key_name}", value]},
89+
}
90+
}
7991
}
80-
}
92+
return connection.mongo_operators[self.lookup_name](lhs_mql, value)
8193

8294

8395
class KeyTransform(Transform):
@@ -88,7 +100,7 @@ def __init__(self, key_name, ref_field, *args, **kwargs):
88100
self.ref_field = ref_field
89101

90102
def get_lookup(self, name):
91-
return self.ref_field.get_lookup(name)
103+
return self.output_field.get_lookup(name)
92104

93105
def get_transform(self, name):
94106
"""
@@ -110,11 +122,12 @@ def get_transform(self, name):
110122
)
111123

112124
def as_mql(self, compiler, connection):
113-
return process_lhs(self, compiler, connection)
125+
lhs_mql = process_lhs(self, compiler, connection)
126+
return f"{lhs_mql}.{self.key_name}"
114127

115128
@property
116129
def output_field(self):
117-
return self.ref_field
130+
return EmbeddedModelArrayField(self.ref_field)
118131

119132

120133
class KeyTransformFactory:

tests/model_fields_/test_embedded_model.py

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

213213
def test_filter_with_embeddedfield_path(self):

0 commit comments

Comments
 (0)