Commit ec186572 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Removed global timezone-aware datetime converters.

Refs #23820.
parent eda12cee
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ class DatabaseCache(BaseDatabaseCache):
            # All core backends work without typecasting, so be careful about
            # changes here - test suite will NOT pick regressions here.
            expires = typecast_timestamp(str(expires))
        if settings.USE_TZ:
            expires = expires.replace(tzinfo=timezone.utc)
        if expires < now:
            db = router.db_for_write(self.cache_model_class)
            with connections[db].cursor() as cursor:
@@ -132,6 +134,8 @@ class DatabaseCache(BaseDatabaseCache):
                        if (connections[db].features.needs_datetime_string_cast and not
                                isinstance(current_expires, datetime)):
                            current_expires = typecast_timestamp(str(current_expires))
                        if settings.USE_TZ:
                            current_expires = current_expires.replace(tzinfo=timezone.utc)
                    exp = connections[db].ops.value_to_db_datetime(exp)
                    if result and (mode == 'set' or (mode == 'add' and current_expires < now)):
                        cursor.execute("UPDATE %s SET value = %%s, expires = %%s "
+0 −14
Original line number Diff line number Diff line
@@ -51,17 +51,6 @@ if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
DatabaseError = Database.DatabaseError
IntegrityError = Database.IntegrityError

# It's impossible to import datetime_or_None directly from MySQLdb.times
parse_datetime = conversions[FIELD_TYPE.DATETIME]


def parse_datetime_with_timezone_support(value):
    dt = parse_datetime(value)
    # Confirm that dt is naive before overwriting its tzinfo.
    if dt is not None and settings.USE_TZ and timezone.is_naive(dt):
        dt = dt.replace(tzinfo=timezone.utc)
    return dt


def adapt_datetime_with_timezone_support(value, conv):
    # Equivalent to DateTimeField.get_db_prep_value. Used only by raw SQL.
@@ -80,14 +69,11 @@ def adapt_datetime_with_timezone_support(value, conv):
# and Django expects time, so we still need to override that. We also need to
# add special handling for SafeText and SafeBytes as MySQLdb's type
# checking is too tight to catch those (see Django ticket #6052).
# Finally, MySQLdb always returns naive datetime objects. However, when
# timezone support is active, Django expects timezone-aware datetime objects.
django_conversions = conversions.copy()
django_conversions.update({
    FIELD_TYPE.TIME: backend_utils.typecast_time,
    FIELD_TYPE.DECIMAL: backend_utils.typecast_decimal,
    FIELD_TYPE.NEWDECIMAL: backend_utils.typecast_decimal,
    FIELD_TYPE.DATETIME: parse_datetime_with_timezone_support,
    datetime.datetime: adapt_datetime_with_timezone_support,
})

+8 −0
Original line number Diff line number Diff line
@@ -184,6 +184,8 @@ class DatabaseOperations(BaseDatabaseOperations):
        internal_type = expression.output_field.get_internal_type()
        if internal_type in ['BooleanField', 'NullBooleanField']:
            converters.append(self.convert_booleanfield_value)
        if internal_type == 'DateTimeField':
            converters.append(self.convert_datetimefield_value)
        if internal_type == 'UUIDField':
            converters.append(self.convert_uuidfield_value)
        if internal_type == 'TextField':
@@ -195,6 +197,12 @@ class DatabaseOperations(BaseDatabaseOperations):
            value = bool(value)
        return value

    def convert_datetimefield_value(self, value, expression, connection, context):
        if value is not None:
            if settings.USE_TZ:
                value = value.replace(tzinfo=timezone.utc)
        return value

    def convert_uuidfield_value(self, value, expression, connection, context):
        if value is not None:
            value = uuid.UUID(value)
+0 −6
Original line number Diff line number Diff line
@@ -588,12 +588,6 @@ def _rowfactory(row, cursor):
                value = decimal.Decimal(value)
            else:
                value = int(value)
        # datetimes are returned as TIMESTAMP, except the results
        # of "dates" queries, which are returned as DATETIME.
        elif desc[1] in (Database.TIMESTAMP, Database.DATETIME):
            # Confirm that dt is naive before overwriting its tzinfo.
            if settings.USE_TZ and value is not None and timezone.is_naive(value):
                value = value.replace(tzinfo=timezone.utc)
        elif desc[1] in (Database.STRING, Database.FIXED_CHAR,
                         Database.LONG_STRING):
            value = to_unicode(value)
+9 −0
Original line number Diff line number Diff line
@@ -163,6 +163,8 @@ WHEN (new.%(col_name)s IS NULL)
            converters.append(self.convert_binaryfield_value)
        elif internal_type in ['BooleanField', 'NullBooleanField']:
            converters.append(self.convert_booleanfield_value)
        elif internal_type == 'DateTimeField':
            converters.append(self.convert_datetimefield_value)
        elif internal_type == 'DateField':
            converters.append(self.convert_datefield_value)
        elif internal_type == 'TimeField':
@@ -202,6 +204,13 @@ WHEN (new.%(col_name)s IS NULL)
    # cx_Oracle always returns datetime.datetime objects for
    # DATE and TIMESTAMP columns, but Django wants to see a
    # python datetime.date, .time, or .datetime.

    def convert_datetimefield_value(self, value, expression, connection, context):
        if value is not None:
            if settings.USE_TZ:
                value = value.replace(tzinfo=timezone.utc)
        return value

    def convert_datefield_value(self, value, expression, connection, context):
        if isinstance(value, Database.Timestamp):
            return value.date()
Loading