Skip to content

Commit 850eeec

Browse files
committed
unfold embedded field into its parent model.
1 parent 2102b39 commit 850eeec

File tree

5 files changed

+27
-64
lines changed

5 files changed

+27
-64
lines changed

django_mongodb_backend/fields/embedded_model.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,20 @@ def formfield(self, **kwargs):
155155
}
156156
)
157157

158+
def contribute_to_class(self, cls, name):
159+
super().contribute_to_class(cls, name)
160+
new_fields = [
161+
*self.embedded_model._meta.local_fields,
162+
*self.embedded_model._meta.private_fields,
163+
]
164+
for field in new_fields:
165+
embedded_field_name = f"{name}.{field.name}"
166+
field = field.clone()
167+
field.unique = False
168+
field.db_index = False
169+
field.name = embedded_field_name
170+
models.Field.contribute_to_class(field, cls, embedded_field_name, private_only=False)
171+
158172

159173
class KeyTransform(Transform):
160174
def __init__(self, key_name, ref_field, *args, **kwargs):

django_mongodb_backend/indexes.py

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from django.core.checks import Error, Warning
55
from django.db import NotSupportedError
6-
from django.db.backends.utils import names_digest, split_identifier
76
from django.db.models import FloatField, Index, IntegerField
87
from django.db.models.lookups import BuiltinLookup
98
from django.db.models.sql.query import Query
@@ -14,7 +13,6 @@
1413
from django_mongodb_backend.fields import ArrayField
1514

1615
from .query_utils import process_rhs
17-
from .utils import get_field
1816

1917
MONGO_INDEX_OPERATORS = {
2018
"exact": "$eq",
@@ -63,7 +61,7 @@ def get_pymongo_index_model(self, model, schema_editor, field=None, unique=False
6361
filter_expression[column].update({"$type": field.db_type(schema_editor.connection)})
6462
else:
6563
for field_name, _ in self.fields_orders:
66-
field_ = get_field(model, field_name)
64+
field_ = model._meta.get_field(field_name)
6765
filter_expression[field_.column].update(
6866
{"$type": field_.db_type(schema_editor.connection)}
6967
)
@@ -76,7 +74,7 @@ def get_pymongo_index_model(self, model, schema_editor, field=None, unique=False
7674
# order is "" if ASCENDING or "DESC" if DESCENDING (see
7775
# django.db.models.indexes.Index.fields_orders).
7876
(
79-
column_prefix + get_field(model, field_name).column,
77+
column_prefix + model._meta.get_field(field_name).column,
8078
ASCENDING if order == "" else DESCENDING,
8179
)
8280
for field_name, order in self.fields_orders
@@ -156,7 +154,7 @@ def get_pymongo_index_model(
156154
for field_name, _ in self.fields_orders:
157155
field = model._meta.get_field(field_name)
158156
type_ = self.search_index_data_types(field.db_type(schema_editor.connection))
159-
field_path = column_prefix + get_field(model, field_name).column
157+
field_path = column_prefix + model._meta.get_field(field_name).column
160158
fields[field_path] = {"type": type_}
161159
return SearchIndexModel(
162160
definition={"mappings": {"dynamic": False, "fields": fields}}, name=self.name
@@ -266,7 +264,7 @@ def get_pymongo_index_model(
266264
fields = []
267265
for field_name, _ in self.fields_orders:
268266
field_ = model._meta.get_field(field_name)
269-
field_path = column_prefix + get_field(model, field_name).column
267+
field_path = column_prefix + model._meta.get_field(field_name).column
270268
mappings = {"path": field_path}
271269
if isinstance(field_, ArrayField):
272270
mappings.update(
@@ -282,38 +280,8 @@ def get_pymongo_index_model(
282280
return SearchIndexModel(definition={"fields": fields}, name=self.name, type="vectorSearch")
283281

284282

285-
def set_name_with_model(self, model):
286-
"""
287-
Generate a unique name for the index.
288-
289-
The name is divided into 3 parts - table name (12 chars), field name
290-
(8 chars) and unique hash + suffix (10 chars). Each part is made to
291-
fit its size by truncating the excess length.
292-
"""
293-
_, table_name = split_identifier(model._meta.db_table)
294-
column_names = [get_field(model, field_name).column for field_name, order in self.fields_orders]
295-
column_names_with_order = [
296-
(f"-{column_name}" if order else column_name)
297-
for column_name, (field_name, order) in zip(column_names, self.fields_orders, strict=False)
298-
]
299-
# The length of the parts of the name is based on the default max
300-
# length of 30 characters.
301-
hash_data = [table_name, *column_names_with_order, self.suffix]
302-
self.name = (
303-
f"{table_name[:11]}_{column_names[0][:7]}_"
304-
f"{names_digest(*hash_data, length=6)}_{self.suffix}"
305-
)
306-
if len(self.name) > self.max_name_length:
307-
raise ValueError(
308-
"Index too long for multiple database support. Is self.suffix longer than 3 characters?"
309-
)
310-
if self.name[0] == "_" or self.name[0].isdigit():
311-
self.name = f"D{self.name[1:]}"
312-
313-
314283
def register_indexes():
315284
BuiltinLookup.as_mql_idx = builtin_lookup_idx
316285
Index._get_condition_mql = _get_condition_mql
317286
Index.get_pymongo_index_model = get_pymongo_index_model
318-
Index.set_name_with_model = set_name_with_model
319287
WhereNode.as_mql_idx = where_node_idx

django_mongodb_backend/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .fields import EmbeddedModelField
88
from .gis.schema import GISSchemaEditor
99
from .query import wrap_database_errors
10-
from .utils import OperationCollector, get_field
10+
from .utils import OperationCollector
1111

1212

1313
def ignore_embedded_models(func):
@@ -249,7 +249,7 @@ def alter_unique_together(
249249
)
250250
# Created uniques
251251
for field_names in news.difference(olds):
252-
columns = [get_field(model, field).column for field in field_names]
252+
columns = [model._meta.get_field(field).column for field in field_names]
253253
name = str(
254254
self._unique_constraint_name(
255255
model._meta.db_table, [column_prefix + col for col in columns]

django_mongodb_backend/utils.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from django.conf import settings
66
from django.core.exceptions import ImproperlyConfigured, ValidationError
77
from django.db.backends.utils import logger
8-
from django.db.models.constants import LOOKUP_SEP
98
from django.utils.functional import SimpleLazyObject
109
from django.utils.text import format_lazy
1110
from django.utils.version import get_version_tuple
@@ -187,21 +186,3 @@ def wrapper(self, *args, **kwargs):
187186
self.log(method, args, kwargs)
188187

189188
return wrapper
190-
191-
192-
def get_field(model, field_name):
193-
from .fields import EmbeddedModelField # noqa: PLC0415
194-
195-
if LOOKUP_SEP in field_name:
196-
previous = model
197-
keys = field_name.split(LOOKUP_SEP)
198-
path = []
199-
for field in keys:
200-
field = previous._meta.get_field(field)
201-
previous = field.embedded_model if isinstance(field, EmbeddedModelField) else field
202-
path.append(field.column)
203-
column = ".".join(path)
204-
embedded_column = field.clone()
205-
embedded_column.column = column
206-
return embedded_column
207-
return model._meta.get_field(field_name)

tests/schema_/test_embedded_model.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,10 @@ class Book(models.Model):
545545
class Meta:
546546
app_label = "schema_"
547547
unique_together = [
548-
("author__unique_together_three", "author__unique_together_four"),
548+
("author.unique_together_three", "author.unique_together_four"),
549549
(
550-
"author__address__unique_together_one",
551-
"author__address__unique_together_two",
550+
"author.address.unique_together_one",
551+
"author.address.unique_together_two",
552552
),
553553
]
554554

@@ -599,8 +599,8 @@ class Book(models.Model):
599599
class Meta:
600600
app_label = "schema_"
601601
indexes = [
602-
models.Index(fields=["author__indexed_two"]),
603-
models.Index(fields=["author__address__indexed_one"]),
602+
models.Index(fields=["author.indexed_two"]),
603+
models.Index(fields=["author.address.indexed_one"]),
604604
]
605605

606606
new_field = EmbeddedModelField(Author)
@@ -649,11 +649,11 @@ class Meta:
649649
app_label = "schema_"
650650
constraints = [
651651
models.UniqueConstraint(
652-
fields=["author__unique_constraint_two"],
652+
fields=["author.unique_constraint_two"],
653653
name="unique_two",
654654
),
655655
models.UniqueConstraint(
656-
fields=["author__address__unique_constraint_one"],
656+
fields=["author.address.unique_constraint_one"],
657657
name="unique_one",
658658
),
659659
]

0 commit comments

Comments
 (0)