Skip to content

Commit f91a5ea

Browse files
committed
remove unnecessary $literal wrapping in Value.as_mql()
It only needs to wrap integers, and wrapping over types causes incorrect matching in ArrayField.
1 parent 3aa239c commit f91a5ea

File tree

2 files changed

+21
-21
lines changed

2 files changed

+21
-21
lines changed

django_mongodb/expressions.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,20 +204,24 @@ def when(self, compiler, connection):
204204

205205
def value(self, compiler, connection): # noqa: ARG001
206206
value = self.value
207+
if isinstance(value, int):
208+
# Wrap numbers in $literal to prevent ambiguity when Value appears in
209+
# $project.
210+
return {"$literal": value}
207211
if isinstance(value, Decimal):
208-
value = Decimal128(value)
209-
elif isinstance(value, datetime.date):
212+
return Decimal128(value)
213+
if isinstance(value, datetime.date):
210214
# Turn dates into datetimes since BSON doesn't support dates.
211-
value = datetime.datetime.combine(value, datetime.datetime.min.time())
212-
elif isinstance(value, datetime.time):
215+
return datetime.datetime.combine(value, datetime.datetime.min.time())
216+
if isinstance(value, datetime.time):
213217
# Turn times into datetimes since BSON doesn't support times.
214-
value = datetime.datetime.combine(datetime.datetime.min.date(), value)
215-
elif isinstance(value, datetime.timedelta):
218+
return datetime.datetime.combine(datetime.datetime.min.date(), value)
219+
if isinstance(value, datetime.timedelta):
216220
# DurationField stores milliseconds rather than microseconds.
217-
value /= datetime.timedelta(milliseconds=1)
218-
elif isinstance(value, UUID):
219-
value = value.hex
220-
return {"$literal": value}
221+
return value / datetime.timedelta(milliseconds=1)
222+
if isinstance(value, UUID):
223+
return value.hex
224+
return value
221225

222226

223227
def register_expressions():

tests/expressions_/test_value.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,33 @@ class ValueTests(SimpleTestCase):
1111
def test_date(self):
1212
self.assertEqual(
1313
Value(datetime.date(2025, 1, 1)).as_mql(None, None),
14-
{"$literal": datetime.datetime(2025, 1, 1)},
14+
datetime.datetime(2025, 1, 1),
1515
)
1616

1717
def test_datetime(self):
1818
self.assertEqual(
1919
Value(datetime.datetime(2025, 1, 1, 9, 8, 7)).as_mql(None, None),
20-
{"$literal": datetime.datetime(2025, 1, 1)},
20+
datetime.datetime(2025, 1, 1),
2121
)
2222

2323
def test_decimal(self):
24-
self.assertEqual(Value(Decimal("1.0")).as_mql(None, None), {"$literal": Decimal128("1.0")})
24+
self.assertEqual(Value(Decimal("1.0")).as_mql(None, None), Decimal128("1.0"))
2525

2626
def test_time(self):
2727
self.assertEqual(
2828
Value(datetime.time(9, 8, 7)).as_mql(None, None),
29-
{"$literal": datetime.datetime(1, 1, 1, 9, 8, 7)},
29+
datetime.datetime(1, 1, 1, 9, 8, 7),
3030
)
3131

3232
def test_timedelta(self):
33-
self.assertEqual(
34-
Value(datetime.timedelta(3600)).as_mql(None, None), {"$literal": 311040000000.0}
35-
)
33+
self.assertEqual(Value(datetime.timedelta(3600)).as_mql(None, None), 311040000000.0)
3634

3735
def test_int(self):
3836
self.assertEqual(Value(1).as_mql(None, None), {"$literal": 1})
3937

4038
def test_str(self):
41-
self.assertEqual(Value("foo").as_mql(None, None), {"$literal": "foo"})
39+
self.assertEqual(Value("foo").as_mql(None, None), "foo")
4240

4341
def test_uuid(self):
4442
value = uuid.UUID(int=1)
45-
self.assertEqual(
46-
Value(value).as_mql(None, None), {"$literal": "00000000000000000000000000000001"}
47-
)
43+
self.assertEqual(Value(value).as_mql(None, None), "00000000000000000000000000000001")

0 commit comments

Comments
 (0)