Skip to content

Commit 2b5b287

Browse files
committed
Refactor
1 parent 8f9c340 commit 2b5b287

File tree

3 files changed

+53
-50
lines changed

3 files changed

+53
-50
lines changed

django_mongodb_backend/fields/embedded_model_array.py

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,55 +69,56 @@ class EMFArrayExact(EMFExact):
6969
def as_mql(self, compiler, connection):
7070
lhs_mql = process_lhs(self, compiler, connection)
7171
value = process_rhs(self, compiler, connection)
72-
if isinstance(self.lhs, Col | KeyTransform):
73-
if isinstance(self.lhs, Col):
74-
inner_lhs_mql = "$$item"
75-
else:
76-
lhs_mql, inner_lhs_mql = lhs_mql
77-
if isinstance(value, models.Model):
78-
value, emf_data = self.model_to_dict(value)
79-
# Get conditions for any nested EmbeddedModelFields.
80-
conditions = self.get_conditions({inner_lhs_mql: (value, emf_data)})
81-
return {
82-
"$anyElementTrue": {
83-
"$ifNull": [
84-
{
85-
"$map": {
86-
"input": lhs_mql,
87-
"as": "item",
88-
"in": {"$and": conditions},
89-
}
90-
},
91-
[],
92-
]
93-
}
94-
}
72+
if isinstance(self.lhs, KeyTransform):
73+
lhs_mql, inner_lhs_mql = lhs_mql
74+
else:
75+
inner_lhs_mql = "$$item"
76+
if isinstance(value, models.Model):
77+
value, emf_data = self.model_to_dict(value)
78+
# Get conditions for any nested EmbeddedModelFields.
79+
conditions = self.get_conditions({inner_lhs_mql: (value, emf_data)})
9580
return {
9681
"$anyElementTrue": {
9782
"$ifNull": [
9883
{
9984
"$map": {
10085
"input": lhs_mql,
10186
"as": "item",
102-
"in": {"$eq": [inner_lhs_mql, value]},
87+
"in": {"$and": conditions},
10388
}
10489
},
10590
[],
10691
]
10792
}
10893
}
109-
return connection.mongo_operators[self.lookup_name](lhs_mql, value)
94+
return {
95+
"$anyElementTrue": {
96+
"$ifNull": [
97+
{
98+
"$map": {
99+
"input": lhs_mql,
100+
"as": "item",
101+
"in": {"$eq": [inner_lhs_mql, value]},
102+
}
103+
},
104+
[],
105+
]
106+
}
107+
}
110108

111109

112110
class KeyTransform(Transform):
113111
# it should be different class than EMF keytransform even most of the methods are equal.
114112
def __init__(self, key_name, base_field, *args, **kwargs):
115113
super().__init__(*args, **kwargs)
116114
self.base_field = base_field
117-
# TODO: Need to create a column, will refactor this thing.
115+
self.key_name = key_name
116+
# The iteration items begins from the base_field, a virtual column with
117+
# base field output type is created.
118118
column_target = base_field.clone()
119-
column_target.db_column = f"$item.{key_name}"
120-
column_target.set_attributes_from_name(f"$item.{key_name}")
119+
column_name = f"$item.{key_name}"
120+
column_target.db_column = column_name
121+
column_target.set_attributes_from_name(column_name)
121122
self._lhs = Col(None, column_target)
122123
self._sub_transform = None
123124

@@ -128,19 +129,8 @@ def __call__(self, this, *args, **kwargs):
128129
def get_lookup(self, name):
129130
return self.output_field.get_lookup(name)
130131

131-
def get_transform(self, name):
132-
"""
133-
Validate that `name` is either a field of an embedded model or a
134-
lookup on an embedded model's field.
135-
"""
136-
if isinstance(self._lhs, Transform):
137-
transform = self._lhs.get_transform(name)
138-
else:
139-
transform = self.base_field.get_transform(name)
140-
if transform:
141-
self._sub_transform = transform
142-
return self
143-
suggested_lookups = difflib.get_close_matches(name, self.base_field.get_lookups())
132+
def _get_missing_field_or_lookup_exception(self, lhs, name):
133+
suggested_lookups = difflib.get_close_matches(name, lhs.get_lookups())
144134
if suggested_lookups:
145135
suggested_lookups = " or ".join(suggested_lookups)
146136
suggestion = f", perhaps you meant {suggested_lookups}?"
@@ -152,6 +142,25 @@ def get_transform(self, name):
152142
f"{suggestion}"
153143
)
154144

145+
def get_transform(self, name):
146+
"""
147+
Validate that `name` is either a field of an embedded model or a
148+
lookup on an embedded model's field.
149+
"""
150+
# Once the sub lhs is a transform, all the filter are applied over it.
151+
152+
transform = (
153+
self._lhs.get_transform(name)
154+
if isinstance(self._lhs, Transform)
155+
else self.base_field.get_transform(name)
156+
)
157+
if transform:
158+
self._sub_transform = transform
159+
return self
160+
raise self._get_missing_field_or_lookup_exception(
161+
self._lhs if isinstance(self._lhs, Transform) else self.base_field, name
162+
)
163+
155164
def as_mql(self, compiler, connection):
156165
inner_lhs_mql = self._lhs.as_mql(compiler, connection)
157166
lhs_mql = process_lhs(self, compiler, connection)

tests/model_fields_/models.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,12 @@ class ExhibitSection(EmbeddedModel):
188188
artifacts = EmbeddedModelArrayField(ArtifactDetail, null=True)
189189

190190

191-
class ExhibitMeta(EmbeddedModel):
192-
curator_name = models.CharField(max_length=255)
193-
artifacts = EmbeddedModelArrayField(ArtifactDetail, null=True)
194-
195-
196191
class MuseumExhibit(models.Model):
197192
"""An exhibit in the museum, composed of multiple sections."""
198193

199194
exhibit_name = models.CharField(max_length=255)
200195
sections = EmbeddedModelArrayField(ExhibitSection, null=True)
201-
meta = EmbeddedModelField(ExhibitMeta, null=True)
196+
main_section = EmbeddedModelField(ExhibitSection, null=True)
202197

203198
def __str__(self):
204199
return self.exhibit_name

tests/model_fields_/test_embedded_model.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
Author,
2424
Book,
2525
Data,
26-
ExhibitMeta,
2726
ExhibitSection,
2827
Holder,
2928
Library,
@@ -202,8 +201,8 @@ def setUpTestData(cls):
202201
)
203202
cls.lost_empires = MuseumExhibit.objects.create(
204203
exhibit_name="Lost Empires",
205-
meta=ExhibitMeta(
206-
curator_name="Dr. Amina Hale",
204+
main_section=ExhibitSection(
205+
section_number=3,
207206
artifacts=[
208207
ArtifactDetail(
209208
name="Bronze Statue",

0 commit comments

Comments
 (0)