summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/core/cache/backends/db.py4
-rw-r--r--django/db/backends/mysql/base.py14
-rw-r--r--django/db/backends/mysql/operations.py8
-rw-r--r--django/db/backends/oracle/base.py6
-rw-r--r--django/db/backends/oracle/operations.py9
-rw-r--r--django/db/backends/sqlite3/base.py11
-rw-r--r--django/db/backends/sqlite3/operations.py21
-rw-r--r--django/db/backends/sqlite3/utils.py11
8 files changed, 39 insertions, 45 deletions
diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py
index a41b611d5b..6b9716b430 100644
--- a/django/core/cache/backends/db.py
+++ b/django/core/cache/backends/db.py
@@ -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 "
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index f31697dadc..4c8809fdb7 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -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,
})
diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py
index bc53f59ec5..3de35c7891 100644
--- a/django/db/backends/mysql/operations.py
+++ b/django/db/backends/mysql/operations.py
@@ -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)
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index d79b582e82..b84b28b97b 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -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)
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index 32dd627216..2ef8caf4e5 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -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()
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 6eb39ad2c3..4cc6266893 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -17,7 +17,9 @@ from django.db.backends import utils as backend_utils
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.backends.base.validation import BaseDatabaseValidation
from django.utils import six, timezone
-from django.utils.dateparse import parse_date, parse_duration, parse_time
+from django.utils.dateparse import (
+ parse_date, parse_datetime, parse_duration, parse_time,
+)
from django.utils.encoding import force_text
from django.utils.safestring import SafeBytes
@@ -42,7 +44,6 @@ from .features import DatabaseFeatures # isort:skip
from .introspection import DatabaseIntrospection # isort:skip
from .operations import DatabaseOperations # isort:skip
from .schema import DatabaseSchemaEditor # isort:skip
-from .utils import parse_datetime_with_timezone_support # isort:skip
DatabaseError = Database.DatabaseError
IntegrityError = Database.IntegrityError
@@ -71,9 +72,9 @@ def decoder(conv_func):
Database.register_converter(str("bool"), decoder(lambda s: s == '1'))
Database.register_converter(str("time"), decoder(parse_time))
Database.register_converter(str("date"), decoder(parse_date))
-Database.register_converter(str("datetime"), decoder(parse_datetime_with_timezone_support))
-Database.register_converter(str("timestamp"), decoder(parse_datetime_with_timezone_support))
-Database.register_converter(str("TIMESTAMP"), decoder(parse_datetime_with_timezone_support))
+Database.register_converter(str("datetime"), decoder(parse_datetime))
+Database.register_converter(str("timestamp"), decoder(parse_datetime))
+Database.register_converter(str("TIMESTAMP"), decoder(parse_datetime))
Database.register_converter(str("decimal"), decoder(backend_utils.typecast_decimal))
Database.register_adapter(datetime.datetime, adapt_datetime_with_timezone_support)
diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py
index f7e2c64da1..3505ebda03 100644
--- a/django/db/backends/sqlite3/operations.py
+++ b/django/db/backends/sqlite3/operations.py
@@ -10,11 +10,9 @@ from django.db.backends import utils as backend_utils
from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.models import aggregates, fields
from django.utils import six, timezone
-from django.utils.dateparse import parse_date, parse_time
+from django.utils.dateparse import parse_date, parse_datetime, parse_time
from django.utils.duration import duration_string
-from .utils import parse_datetime_with_timezone_support
-
try:
import pytz
except ImportError:
@@ -157,18 +155,23 @@ class DatabaseOperations(BaseDatabaseOperations):
return backend_utils.typecast_decimal(expression.output_field.format_number(value))
def convert_datefield_value(self, value, expression, connection, context):
- if value is not None and not isinstance(value, datetime.date):
- value = parse_date(value)
+ if value is not None:
+ if not isinstance(value, datetime.date):
+ value = parse_date(value)
return value
def convert_datetimefield_value(self, value, expression, connection, context):
- if value is not None and not isinstance(value, datetime.datetime):
- value = parse_datetime_with_timezone_support(value)
+ if value is not None:
+ if not isinstance(value, datetime.datetime):
+ value = parse_datetime(value)
+ if settings.USE_TZ:
+ value = value.replace(tzinfo=timezone.utc)
return value
def convert_timefield_value(self, value, expression, connection, context):
- if value is not None and not isinstance(value, datetime.time):
- value = parse_time(value)
+ if value is not None:
+ if not isinstance(value, datetime.time):
+ value = parse_time(value)
return value
def convert_uuidfield_value(self, value, expression, connection, context):
diff --git a/django/db/backends/sqlite3/utils.py b/django/db/backends/sqlite3/utils.py
deleted file mode 100644
index 6a8b3b8943..0000000000
--- a/django/db/backends/sqlite3/utils.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.conf import settings
-from django.utils import timezone
-from django.utils.dateparse import parse_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