Skip to content

Commit 8d6af32

Browse files
committed
add support for direct field queries
1 parent 5195c89 commit 8d6af32

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

7991

8092
class KeyTransform(Transform):
@@ -85,7 +97,7 @@ def __init__(self, key_name, ref_field, *args, **kwargs):
8597
self.ref_field = ref_field
8698

8799
def get_lookup(self, name):
88-
return self.ref_field.get_lookup(name)
100+
return self.output_field.get_lookup(name)
89101

90102
def get_transform(self, name):
91103
"""
@@ -107,11 +119,12 @@ def get_transform(self, name):
107119
)
108120

109121
def as_mql(self, compiler, connection):
110-
return process_lhs(self, compiler, connection)
122+
lhs_mql = process_lhs(self, compiler, connection)
123+
return f"{lhs_mql}.{self.key_name}"
111124

112125
@property
113126
def output_field(self):
114-
return self.ref_field
127+
return EmbeddedModelArrayField(self.ref_field)
115128

116129

117130
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)