Open
Description
Unlike Value.as_sql()
, Value.as_mql()
doesn't call output_field.get_db_prep_save()
. This hasn't been a problem on any tests except for a new one in Django 5.2, model_fields.test_jsonfield.TestSaveLoad.test_bulk_update_custom_get_prep_value
.
I'm not sure how needful this fix is, and since the patch I wrote breaks another test (perhaps revealing a server-side bug), I'm just going to leave it here for now.
commit 5c7433e1f6e94b89ef87b3ba505c491e1f8fe84e
Author: Tim Graham <[email protected]>
Date: Fri Feb 21 20:01:42 2025 -0500
fix model_fields.test_jsonfield.TestSaveLoad.test_bulk_update_custom_get_prep_value
https://github.com/django/django/commit/9525135698bd4f97cf1431776ef52ae393dfb3c0
diff --git a/django_mongodb_backend/expressions.py b/django_mongodb_backend/expressions.py
index e5ef335..2bf7e0e 100644
--- a/django_mongodb_backend/expressions.py
+++ b/django_mongodb_backend/expressions.py
@@ -186,6 +186,12 @@ def when(self, compiler, connection):
def value(self, compiler, connection): # noqa: ARG001
value = self.value
+ output_field = self._output_field_or_none
+ if output_field is not None:
+ if self.for_save:
+ value = output_field.get_db_prep_save(value, connection=connection)
+ else:
+ value = output_field.get_db_prep_value(value, connection=connection)
if isinstance(value, int):
# Wrap numbers in $literal to prevent ambiguity when Value appears in
# $project.
diff --git a/django_mongodb_backend/features.py b/django_mongodb_backend/features.py
index 1317a72..bb709b1 100644
--- a/django_mongodb_backend/features.py
+++ b/django_mongodb_backend/features.py
@@ -98,6 +98,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"prefetch_related.tests.NestedPrefetchTests.test_nested_prefetch_is_not_overwritten_by_related_object",
"prefetch_related.tests.NullableTest.test_prefetch_nullable",
"prefetch_related.tests.Ticket19607Tests.test_bug",
+ # {'$project': {'name': Decimal128('1')} is broken? (gives None)
+ "expressions.tests.ValueTests.test_output_field_decimalfield",
}
# $bitAnd, #bitOr, and $bitXor are new in MongoDB 6.3.
_django_test_expected_failures_bitwise = {
diff --git a/tests/expressions_/test_value.py b/tests/expressions_/test_value.py
index c57c2f0..ad131a7 100644
--- a/tests/expressions_/test_value.py
+++ b/tests/expressions_/test_value.py
@@ -3,6 +3,7 @@ import uuid
from decimal import Decimal
from bson import Decimal128
+from django.db import connection
from django.db.models import Value
from django.test import SimpleTestCase
@@ -10,34 +11,36 @@ from django.test import SimpleTestCase
class ValueTests(SimpleTestCase):
def test_date(self):
self.assertEqual(
- Value(datetime.date(2025, 1, 1)).as_mql(None, None),
+ Value(datetime.date(2025, 1, 1)).as_mql(None, connection),
datetime.datetime(2025, 1, 1),
)
def test_datetime(self):
self.assertEqual(
- Value(datetime.datetime(2025, 1, 1, 9, 8, 7)).as_mql(None, None),
+ Value(datetime.datetime(2025, 1, 1, 9, 8, 7)).as_mql(None, connection),
datetime.datetime(2025, 1, 1, 9, 8, 7),
)
def test_decimal(self):
- self.assertEqual(Value(Decimal("1.0")).as_mql(None, None), Decimal128("1.0"))
+ self.assertEqual(Value(Decimal("1.0")).as_mql(None, connection), Decimal128("1.0"))
def test_time(self):
self.assertEqual(
- Value(datetime.time(9, 8, 7)).as_mql(None, None),
+ Value(datetime.time(9, 8, 7)).as_mql(None, connection),
datetime.datetime(1, 1, 1, 9, 8, 7),
)
def test_timedelta(self):
- self.assertEqual(Value(datetime.timedelta(3600)).as_mql(None, None), 311040000000.0)
+ self.assertEqual(
+ Value(datetime.timedelta(3600)).as_mql(None, connection), {"$literal": 311040000000}
+ )
def test_int(self):
- self.assertEqual(Value(1).as_mql(None, None), {"$literal": 1})
+ self.assertEqual(Value(1).as_mql(None, connection), {"$literal": 1})
def test_str(self):
- self.assertEqual(Value("foo").as_mql(None, None), "foo")
+ self.assertEqual(Value("foo").as_mql(None, connection), "foo")
def test_uuid(self):
value = uuid.UUID(int=1)
- self.assertEqual(Value(value).as_mql(None, None), "00000000000000000000000000000001")
+ self.assertEqual(Value(value).as_mql(None, connection), "00000000000000000000000000000001")
Metadata
Metadata
Assignees
Labels
No labels