Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions django_mongodb_backend/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ def get_db_converters(self, expression):
converters.append(self.convert_datetimefield_value)
elif internal_type == "DecimalField":
converters.append(self.convert_decimalfield_value)
elif internal_type == "EmbeddedModelField":
converters.append(self.convert_embeddedmodelfield_value)
elif internal_type == "JSONField":
converters.append(self.convert_jsonfield_value)
elif internal_type == "TimeField":
Expand Down Expand Up @@ -150,6 +152,16 @@ def convert_durationfield_value(self, value, expression, connection):
value = datetime.timedelta(milliseconds=int(str(value)))
return value

def convert_embeddedmodelfield_value(self, value, expression, connection):
if value is not None:
# Apply database converters to each field of the embedded model.
for field in expression.output_field.embedded_model._meta.fields:
field_expr = Expression(output_field=field)
converters = connection.ops.get_db_converters(field_expr)
for converter in converters:
value[field.attname] = converter(value[field.attname], field_expr, connection)
return value

def convert_jsonfield_value(self, value, expression, connection):
"""
Convert dict data to a string so that JSONField.from_db_value() can
Expand Down
3 changes: 3 additions & 0 deletions docs/source/releases/5.1.x.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Django MongoDB Backend 5.1.x
- Fixed the results of queries that use the ``tzinfo`` parameter of the
``Trunc`` database functions.
- Added support for ``QuerySet.dates()`` and ``datetimes()``.
- Fixed loading of ``QuerySet`` results for embedded models that have fields
that use database converters. For example, a crash for ``DecimalField``:
``ValidationError: ['“1” value must be a decimal number.']``).

.. _django-mongodb-backend-5.1.0-beta-2:

Expand Down
3 changes: 3 additions & 0 deletions docs/source/releases/5.2.x.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ Bug fixes
- Fixed the results of queries that use the ``tzinfo`` parameter of the
``Trunc`` database functions.
- Added support for ``QuerySet.dates()`` and ``datetimes()``.
- Fixed loading of ``QuerySet`` results for embedded models that have fields
that use database converters. For example, a crash for ``DecimalField``:
``ValidationError: ['“1” value must be a decimal number.']``).
6 changes: 6 additions & 0 deletions tests/model_fields_/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ class Data(EmbeddedModel):
auto_now = models.DateTimeField(auto_now=True)
auto_now_add = models.DateTimeField(auto_now_add=True)
json_value = models.JSONField()
decimal = models.DecimalField(max_digits=9, decimal_places="2", null=True, blank=True)
nested_data = EmbeddedModelField("NestedData", null=True, blank=True)


class NestedData(EmbeddedModel):
decimal = models.DecimalField(max_digits=9, decimal_places="2", null=True, blank=True)


class Address(EmbeddedModel):
Expand Down
25 changes: 24 additions & 1 deletion tests/model_fields_/test_embedded_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
Data,
Holder,
Library,
NestedData,
)
from .utils import truncate_ms

Expand Down Expand Up @@ -93,7 +94,16 @@ def test_pre_save(self):
class QueryingTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.objs = [Holder.objects.create(data=Data(integer=x)) for x in range(6)]
cls.objs = [
Holder.objects.create(
data=Data(
integer=x,
decimal=f"{x}.5",
nested_data=NestedData(decimal=f"{x}.5"),
)
)
for x in range(6)
]

def test_exact(self):
self.assertCountEqual(Holder.objects.filter(data__integer=3), [self.objs[3]])
Expand All @@ -113,6 +123,19 @@ def test_gte(self):
def test_range(self):
self.assertCountEqual(Holder.objects.filter(data__integer__range=(2, 4)), self.objs[2:5])

def test_exact_decimal(self):
# EmbeddedModelField lookups call
# DatabaseOperations.adapt__<foo>field_value().
self.assertCountEqual(Holder.objects.filter(data__decimal="3.5"), [self.objs[3]])

def test_lt_decimal(self):
self.assertCountEqual(Holder.objects.filter(data__decimal__lt="3"), self.objs[0:3])

def test_exact_decimal_nested(self):
self.assertCountEqual(
Holder.objects.filter(data__nested_data__decimal="3.5"), [self.objs[3]]
)

def test_order_by_embedded_field(self):
qs = Holder.objects.filter(data__integer__gt=3).order_by("-data__integer")
self.assertSequenceEqual(qs, list(reversed(self.objs[4:])))
Expand Down
Loading