From 202eca7795710c82cd64a248650afc64f905a17e Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 16 Feb 2026 21:27:35 -0500 Subject: Added DatabaseOperations.convert_trunc_expression() hook. Needed on MongoDB. --- django/db/backends/base/operations.py | 21 ++++++++++++++++++++- django/db/models/functions/datetime.py | 20 +------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index fac6215899..bc1752df6f 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -7,7 +7,7 @@ from itertools import chain import sqlparse from django.conf import settings -from django.db import NotSupportedError, transaction +from django.db import NotSupportedError, models, transaction from django.db.models.expressions import Col from django.db.models.fields.composite import CompositePrimaryKey from django.utils import timezone @@ -684,6 +684,25 @@ class BaseDatabaseOperations: if value is not None: return datetime.timedelta(0, 0, value) + def convert_trunc_expression(self, value, expression): + if isinstance(expression.output_field, models.DateTimeField): + if not settings.USE_TZ: + pass + elif value is not None: + value = value.replace(tzinfo=None) + value = timezone.make_aware(value, expression.tzinfo) + elif not self.connection.features.has_zoneinfo_database: + raise ValueError( + "Database returned an invalid datetime value. Are time " + "zone definitions for your database installed?" + ) + elif isinstance(value, datetime.datetime): + if isinstance(expression.output_field, models.DateField): + value = value.date() + elif isinstance(expression.output_field, models.TimeField): + value = value.time() + return value + def check_expression_support(self, expression): """ Check that the backend supports the provided expression. diff --git a/django/db/models/functions/datetime.py b/django/db/models/functions/datetime.py index b536690c8a..842987bf26 100644 --- a/django/db/models/functions/datetime.py +++ b/django/db/models/functions/datetime.py @@ -1,5 +1,3 @@ -from datetime import datetime - from django.conf import settings from django.db.models.expressions import Func from django.db.models.fields import ( @@ -344,23 +342,7 @@ class TruncBase(TimezoneMixin, Transform): return copy def convert_value(self, value, expression, connection): - if isinstance(self.output_field, DateTimeField): - if not settings.USE_TZ: - pass - elif value is not None: - value = value.replace(tzinfo=None) - value = timezone.make_aware(value, self.tzinfo) - elif not connection.features.has_zoneinfo_database: - raise ValueError( - "Database returned an invalid datetime value. Are time " - "zone definitions for your database installed?" - ) - elif isinstance(value, datetime): - if isinstance(self.output_field, DateField): - value = value.date() - elif isinstance(self.output_field, TimeField): - value = value.time() - return value + return connection.ops.convert_trunc_expression(value, expression) class Trunc(TruncBase): -- cgit v1.3