summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/core/cache/backends/db.py21
1 files changed, 18 insertions, 3 deletions
diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py
index 0e59c6d65e..8844bc8f61 100644
--- a/django/core/cache/backends/db.py
+++ b/django/core/cache/backends/db.py
@@ -11,6 +11,7 @@ except ImportError:
from django.conf import settings
from django.core.cache.backends.base import BaseCache, DEFAULT_TIMEOUT
from django.db import connections, transaction, router, DatabaseError
+from django.db.backends.utils import typecast_timestamp
from django.utils import timezone, six
from django.utils.encoding import force_bytes
@@ -65,8 +66,13 @@ class DatabaseCache(BaseDatabaseCache):
if row is None:
return default
now = timezone.now()
-
- if row[2] < now:
+ expires = row[2]
+ if connections[db].features.needs_datetime_string_cast and not isinstance(expires, datetime):
+ # Note: typecasting is needed by some 3rd party database backends.
+ # 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 expires < now:
db = router.db_for_write(self.cache_model_class)
cursor = connections[db].cursor()
cursor.execute("DELETE FROM %s "
@@ -112,12 +118,21 @@ class DatabaseCache(BaseDatabaseCache):
if six.PY3:
b64encoded = b64encoded.decode('latin1')
try:
+ # Note: typecasting for datetimes is needed by some 3rd party
+ # database backends. All core backends work without typecasting,
+ # so be careful about changes here - test suite will NOT pick
+ # regressions.
with transaction.atomic(using=db):
cursor.execute("SELECT cache_key, expires FROM %s "
"WHERE cache_key = %%s" % table, [key])
result = cursor.fetchone()
+ if result:
+ current_expires = result[1]
+ if (connections[db].features.needs_datetime_string_cast and not
+ isinstance(current_expires, datetime)):
+ current_expires = typecast_timestamp(str(current_expires))
exp = connections[db].ops.value_to_db_datetime(exp)
- if result and (mode == 'set' or (mode == 'add' and result[1] < now)):
+ if result and (mode == 'set' or (mode == 'add' and current_expires < now)):
cursor.execute("UPDATE %s SET value = %%s, expires = %%s "
"WHERE cache_key = %%s" % table,
[b64encoded, exp, key])