Fixed #22085 -- Added a feature for setting non-expiring keys as the default.
This feature allows the default `TIMEOUT` Cache argument to be set to `None`, so that cache instances can set a non-expiring key as the default, instead of using the default value of 5 minutes. Previously, this was possible only by passing `None` as an argument to the set() method of objects of type `BaseCache` (and subtypes).
This commit is contained in:
parent
24f0113fb9
commit
6fe22b30e0
|
@ -52,6 +52,7 @@ def get_key_func(key_func):
|
||||||
class BaseCache(object):
|
class BaseCache(object):
|
||||||
def __init__(self, params):
|
def __init__(self, params):
|
||||||
timeout = params.get('timeout', params.get('TIMEOUT', 300))
|
timeout = params.get('timeout', params.get('TIMEOUT', 300))
|
||||||
|
if timeout is not None:
|
||||||
try:
|
try:
|
||||||
timeout = int(timeout)
|
timeout = int(timeout)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
|
|
|
@ -255,6 +255,10 @@ Default: 300
|
||||||
|
|
||||||
The number of seconds before a cache entry is considered stale.
|
The number of seconds before a cache entry is considered stale.
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
If the value of this settings is ``None``, cache entries will not expire.
|
||||||
|
|
||||||
.. setting:: CACHES-VERSION
|
.. setting:: CACHES-VERSION
|
||||||
|
|
||||||
VERSION
|
VERSION
|
||||||
|
|
|
@ -441,6 +441,11 @@ Cache
|
||||||
thread-safe any more, as :data:`django.core.cache.caches` now yields
|
thread-safe any more, as :data:`django.core.cache.caches` now yields
|
||||||
different instances per thread.
|
different instances per thread.
|
||||||
|
|
||||||
|
* Defining the :setting:`TIMEOUT <CACHES-TIMEOUT>` argument of the
|
||||||
|
:setting:`CACHES` setting as ``None`` will set the cache keys as
|
||||||
|
"non-expiring" by default. Previously, it was only possible to pass
|
||||||
|
``timeout=None` to the cache backend's ``set()`` method.
|
||||||
|
|
||||||
Email
|
Email
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
|
|
|
@ -363,9 +363,14 @@ Each cache backend can be given additional arguments to control caching
|
||||||
behavior. These arguments are provided as additional keys in the
|
behavior. These arguments are provided as additional keys in the
|
||||||
:setting:`CACHES` setting. Valid arguments are as follows:
|
:setting:`CACHES` setting. Valid arguments are as follows:
|
||||||
|
|
||||||
|
|
||||||
* :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in
|
* :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in
|
||||||
seconds, to use for the cache. This argument defaults to ``300``
|
seconds, to use for the cache. This argument defaults to ``300`` seconds (5 minutes).
|
||||||
seconds (5 minutes).
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
You can set ``TIMEOUT`` to ``None`` so that, by default, cache keys never
|
||||||
|
expire.
|
||||||
|
|
||||||
* :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be
|
* :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be
|
||||||
passed to the cache backend. The list of valid options will vary
|
passed to the cache backend. The list of valid options will vary
|
||||||
|
|
|
@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import copy
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
|
@ -15,7 +16,8 @@ import warnings
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import management
|
from django.core import management
|
||||||
from django.core.cache import cache, caches, CacheKeyWarning, InvalidCacheBackendError
|
from django.core.cache import (cache, caches, CacheKeyWarning,
|
||||||
|
InvalidCacheBackendError, DEFAULT_CACHE_ALIAS)
|
||||||
from django.db import connection, router, transaction
|
from django.db import connection, router, transaction
|
||||||
from django.core.cache.utils import make_template_fragment_key
|
from django.core.cache.utils import make_template_fragment_key
|
||||||
from django.http import HttpResponse, StreamingHttpResponse
|
from django.http import HttpResponse, StreamingHttpResponse
|
||||||
|
@ -1175,7 +1177,7 @@ class CustomCacheKeyValidationTests(TestCase):
|
||||||
class GetCacheTests(IgnorePendingDeprecationWarningsMixin, TestCase):
|
class GetCacheTests(IgnorePendingDeprecationWarningsMixin, TestCase):
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
from django.core.cache import caches, DEFAULT_CACHE_ALIAS, get_cache
|
from django.core.cache import caches, get_cache
|
||||||
self.assertIsInstance(
|
self.assertIsInstance(
|
||||||
caches[DEFAULT_CACHE_ALIAS],
|
caches[DEFAULT_CACHE_ALIAS],
|
||||||
get_cache('default').__class__
|
get_cache('default').__class__
|
||||||
|
@ -1204,6 +1206,82 @@ class GetCacheTests(IgnorePendingDeprecationWarningsMixin, TestCase):
|
||||||
self.assertTrue(cache.closed)
|
self.assertTrue(cache.closed)
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_MEMORY_CACHES_SETTINGS = {
|
||||||
|
'default': {
|
||||||
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||||
|
'LOCATION': 'unique-snowflake',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NEVER_EXPIRING_CACHES_SETTINGS = copy.deepcopy(DEFAULT_MEMORY_CACHES_SETTINGS)
|
||||||
|
NEVER_EXPIRING_CACHES_SETTINGS['default']['TIMEOUT'] = None
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultNonExpiringCacheKeyTests(TestCase):
|
||||||
|
"""Tests that verify that settings having Cache arguments with a TIMEOUT
|
||||||
|
set to `None` will create Caches that will set non-expiring keys.
|
||||||
|
|
||||||
|
This fixes ticket #22085.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
# The 5 minute (300 seconds) default expiration time for keys is
|
||||||
|
# defined in the implementation of the initializer method of the
|
||||||
|
# BaseCache type.
|
||||||
|
self.DEFAULT_TIMEOUT = caches[DEFAULT_CACHE_ALIAS].default_timeout
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
del(self.DEFAULT_TIMEOUT)
|
||||||
|
|
||||||
|
def test_default_expiration_time_for_keys_is_5_minutes(self):
|
||||||
|
"""The default expiration time of a cache key is 5 minutes.
|
||||||
|
|
||||||
|
This value is defined inside the __init__() method of the
|
||||||
|
:class:`django.core.cache.backends.base.BaseCache` type.
|
||||||
|
"""
|
||||||
|
self.assertEquals(300, self.DEFAULT_TIMEOUT)
|
||||||
|
|
||||||
|
def test_caches_with_unset_timeout_has_correct_default_timeout(self):
|
||||||
|
"""Caches that have the TIMEOUT parameter undefined in the default
|
||||||
|
settings will use the default 5 minute timeout.
|
||||||
|
"""
|
||||||
|
cache = caches[DEFAULT_CACHE_ALIAS]
|
||||||
|
self.assertEquals(self.DEFAULT_TIMEOUT, cache.default_timeout)
|
||||||
|
|
||||||
|
@override_settings(CACHES=NEVER_EXPIRING_CACHES_SETTINGS)
|
||||||
|
def test_caches_set_with_timeout_as_none_has_correct_default_timeout(self):
|
||||||
|
"""Memory caches that have the TIMEOUT parameter set to `None` in the
|
||||||
|
default settings with have `None` as the default timeout.
|
||||||
|
|
||||||
|
This means "no timeout".
|
||||||
|
"""
|
||||||
|
cache = caches[DEFAULT_CACHE_ALIAS]
|
||||||
|
self.assertIs(None, cache.default_timeout)
|
||||||
|
self.assertEquals(None, cache.get_backend_timeout())
|
||||||
|
|
||||||
|
@override_settings(CACHES=DEFAULT_MEMORY_CACHES_SETTINGS)
|
||||||
|
def test_caches_with_unset_timeout_set_expiring_key(self):
|
||||||
|
"""Memory caches that have the TIMEOUT parameter unset will set cache
|
||||||
|
keys having the default 5 minute timeout.
|
||||||
|
"""
|
||||||
|
key = "my-key"
|
||||||
|
value = "my-value"
|
||||||
|
cache = caches[DEFAULT_CACHE_ALIAS]
|
||||||
|
cache.set(key, value)
|
||||||
|
cache_key = cache.make_key(key)
|
||||||
|
self.assertNotEquals(None, cache._expire_info[cache_key])
|
||||||
|
|
||||||
|
@override_settings(CACHES=NEVER_EXPIRING_CACHES_SETTINGS)
|
||||||
|
def text_caches_set_with_timeout_as_none_set_non_expiring_key(self):
|
||||||
|
"""Memory caches that have the TIMEOUT parameter set to `None` will set
|
||||||
|
a non expiring key by default.
|
||||||
|
"""
|
||||||
|
key = "another-key"
|
||||||
|
value = "another-value"
|
||||||
|
cache = caches[DEFAULT_CACHE_ALIAS]
|
||||||
|
cache.set(key, value)
|
||||||
|
cache_key = cache.make_key(key)
|
||||||
|
self.assertEquals(None, cache._expire_info[cache_key])
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(
|
||||||
CACHE_MIDDLEWARE_KEY_PREFIX='settingsprefix',
|
CACHE_MIDDLEWARE_KEY_PREFIX='settingsprefix',
|
||||||
CACHE_MIDDLEWARE_SECONDS=1,
|
CACHE_MIDDLEWARE_SECONDS=1,
|
||||||
|
|
Loading…
Reference in New Issue