Skip to content

Commit c406fb5

Browse files
committed
Use DatabaseOperations.convert_trunc_expression()
Proposed for Django 6.1
1 parent d59167b commit c406fb5

2 files changed

Lines changed: 24 additions & 35 deletions

File tree

django_mongodb_backend/functions.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
from datetime import datetime
21
from functools import partialmethod
32

4-
from django.conf import settings
53
from django.db import NotSupportedError
6-
from django.db.models import DateField, DateTimeField, TimeField
74
from django.db.models.expressions import Func
85
from django.db.models.functions import JSONArray
96
from django.db.models.functions.comparison import Cast, Coalesce, Greatest, Least, NullIf
@@ -209,36 +206,6 @@ def trunc(self, compiler, connection):
209206
return {"$dateTrunc": lhs_mql}
210207

211208

212-
_trunc_convert_value = TruncBase.convert_value
213-
214-
215-
def trunc_convert_value(self, value, expression, connection):
216-
if connection.vendor == "mongodb":
217-
# A custom TruncBase.convert_value() for MongoDB.
218-
if value is None:
219-
return None
220-
convert_to_tz = settings.USE_TZ and self.get_tzname() != "UTC"
221-
if isinstance(self.output_field, DateTimeField):
222-
if convert_to_tz:
223-
# Unlike other databases, MongoDB returns the value in UTC,
224-
# so rather than setting the time zone equal to self.tzinfo,
225-
# the value must be converted to tzinfo.
226-
value = value.astimezone(self.tzinfo)
227-
elif isinstance(value, datetime):
228-
if isinstance(self.output_field, DateField):
229-
if convert_to_tz:
230-
value = value.astimezone(self.tzinfo)
231-
# Truncate for Trunc(..., output_field=DateField)
232-
value = value.date()
233-
elif isinstance(self.output_field, TimeField):
234-
if convert_to_tz:
235-
value = value.astimezone(self.tzinfo)
236-
# Truncate for Trunc(..., output_field=TimeField)
237-
value = value.time()
238-
return value
239-
return _trunc_convert_value(self, value, expression, connection)
240-
241-
242209
def trunc_date(self, compiler, connection):
243210
# Cast to date rather than truncate to date.
244211
lhs_mql = process_lhs(self, compiler, connection, as_expr=True)
@@ -311,7 +278,6 @@ def register_functions():
311278
Substr.as_mql_expr = substr
312279
Trim.as_mql_expr = trim("trim")
313280
TruncBase.as_mql_expr = trunc
314-
TruncBase.convert_value = trunc_convert_value
315281
TruncDate.as_mql_expr = trunc_date
316282
TruncTime.as_mql_expr = trunc_time
317283
Upper.as_mql_expr = preserve_null("toUpper")

django_mongodb_backend/operations.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from bson import Decimal128, Int64
88
from django.conf import settings
99
from django.core.exceptions import ImproperlyConfigured
10-
from django.db import DataError
10+
from django.db import DataError, models
1111
from django.db.backends.base.operations import BaseDatabaseOperations
1212
from django.db.models import TextField
1313
from django.db.models.expressions import Combinable, Expression
@@ -235,6 +235,29 @@ def convert_uuidfield_value(self, value, expression, connection):
235235
value = uuid.UUID(value)
236236
return value
237237

238+
def convert_trunc_expression(self, value, expression):
239+
if value is None:
240+
return None
241+
convert_to_tz = settings.USE_TZ and expression.get_tzname() != "UTC"
242+
if isinstance(expression.output_field, models.DateTimeField):
243+
if convert_to_tz:
244+
# Unlike other databases, MongoDB returns the value in UTC,
245+
# so rather than setting the time zone equal to expression.tzinfo,
246+
# the value must be converted to tzinfo.
247+
value = value.astimezone(expression.tzinfo)
248+
elif isinstance(value, datetime.datetime):
249+
if isinstance(expression.output_field, models.DateField):
250+
if convert_to_tz:
251+
value = value.astimezone(expression.tzinfo)
252+
# Truncate for Trunc(..., output_field=DateField)
253+
value = value.date()
254+
elif isinstance(expression.output_field, models.TimeField):
255+
if convert_to_tz:
256+
value = value.astimezone(expression.tzinfo)
257+
# Truncate for Trunc(..., output_field=TimeField)
258+
value = value.time()
259+
return value
260+
238261
def combine_expression(self, connector, sub_expressions):
239262
lhs, rhs = sub_expressions
240263
if connector == Combinable.BITLEFTSHIFT:

0 commit comments

Comments
 (0)