Loading django/core/cache/__init__.py +20 −74 Original line number Diff line number Diff line Loading @@ -8,9 +8,9 @@ the abstract BaseCache class in django.core.cache.backends.base. Client code should not access a cache backend directly; instead it should either use the "cache" variable made available here, or it should use the get_cache() function made available here. get_cache() takes a backend URI (e.g. "memcached://127.0.0.1:11211/") and returns an instance of a backend cache class. get_cache() function made available here. get_cache() takes a CACHES alias or a backend path and config parameters, and returns an instance of a backend cache class. See docs/topics/cache.txt for information on the public API. """ Loading @@ -29,78 +29,17 @@ __all__ = [ 'get_cache', 'cache', 'DEFAULT_CACHE_ALIAS' ] # Name for use in settings file --> name of module in "backends" directory. # Any backend scheme that is not in this dictionary is treated as a Python # import path to a custom backend. BACKENDS = { 'memcached': 'memcached', 'locmem': 'locmem', 'file': 'filebased', 'db': 'db', 'dummy': 'dummy', } DEFAULT_CACHE_ALIAS = 'default' def parse_backend_uri(backend_uri): """ Converts the "backend_uri" into a cache scheme ('db', 'memcached', etc), a host and any extra params that are required for the backend. Returns a (scheme, host, params) tuple. """ if backend_uri.find(':') == -1: raise InvalidCacheBackendError("Backend URI must start with scheme://") scheme, rest = backend_uri.split(':', 1) if not rest.startswith('//'): raise InvalidCacheBackendError("Backend URI must start with scheme://") host = rest[2:] qpos = rest.find('?') if qpos != -1: params = dict(parse_qsl(rest[qpos+1:])) host = rest[2:qpos] else: params = {} if host.endswith('/'): host = host[:-1] return scheme, host, params if DEFAULT_CACHE_ALIAS not in settings.CACHES: raise ImproperlyConfigured("You must define a '%s' cache" % DEFAULT_CACHE_ALIAS) def parse_backend_conf(backend, **kwargs): """ Helper function to parse the backend configuration that doesn't use the URI notation. """ # Try to get the CACHES entry for the given backend name first conf = settings.CACHES.get(backend, None) if conf is not None: args = conf.copy() args.update(kwargs) backend = args.pop('BACKEND') location = args.pop('LOCATION', '') return backend, location, args else: try: # Trying to import the given backend, in case it's a dotted path import_by_path(backend) except ImproperlyConfigured as e: raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( backend, e)) location = kwargs.pop('LOCATION', '') return backend, location, kwargs def get_cache(backend, **kwargs): """ Function to load a cache backend dynamically. This is flexible by design to allow different use cases: To load a backend with the old URI-based notation:: cache = get_cache('locmem://') To load a backend that is pre-defined in the settings:: cache = get_cache('default') Loading @@ -114,16 +53,23 @@ def get_cache(backend, **kwargs): """ try: if '://' in backend: # for backwards compatibility backend, location, params = parse_backend_uri(backend) if backend in BACKENDS: backend = 'django.core.cache.backends.%s' % BACKENDS[backend] params.update(kwargs) mod = importlib.import_module(backend) backend_cls = mod.CacheClass # Try to get the CACHES entry for the given backend name first try: conf = settings.CACHES[backend] except KeyError: try: # Trying to import the given backend, in case it's a dotted path import_by_path(backend) except ImproperlyConfigured as e: raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( backend, e)) location = kwargs.pop('LOCATION', '') params = kwargs else: backend, location, params = parse_backend_conf(backend, **kwargs) params = conf.copy() params.update(kwargs) backend = params.pop('BACKEND') location = params.pop('LOCATION', '') backend_cls = import_by_path(backend) except (AttributeError, ImportError, ImproperlyConfigured) as e: raise InvalidCacheBackendError( Loading docs/releases/1.7.txt +4 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,10 @@ Miscellaneous Rationale behind this is removal of dependency of non-contrib code on contrib applications. * The old cache URI syntax (e.g. ``"locmem://"``) is no longer supported. It still worked, even though it was not documented or officially supported. If you're still using it, please update to the current :setting:`CACHES` syntax. Features deprecated in 1.7 ========================== Loading tests/cache/tests.py +1 −17 Original line number Diff line number Diff line Loading @@ -857,10 +857,6 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): self.cache = get_cache(self.backend_name, LOCATION=self._table_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0}) self.perform_cull_test(50, 18) def test_old_initialization(self): self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name) self.perform_cull_test(50, 18) def test_second_call_doesnt_crash(self): with six.assertRaisesRegex(self, management.CommandError, "Cache table 'test cache table' could not be created"): Loading Loading @@ -956,10 +952,6 @@ class LocMemCacheTests(unittest.TestCase, BaseCacheTests): self.cache = get_cache(self.backend_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0}) self.perform_cull_test(50, 19) def test_old_initialization(self): self.cache = get_cache('locmem://?max_entries=30&cull_frequency=0') self.perform_cull_test(50, 19) def test_multiple_caches(self): "Check that multiple locmem caches are isolated" mirror_cache = get_cache(self.backend_name) Loading Loading @@ -1075,10 +1067,6 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests): def test_cull(self): self.perform_cull_test(50, 29) def test_old_initialization(self): self.cache = get_cache('file://%s?max_entries=30' % self.dirname) self.perform_cull_test(50, 29) class CustomCacheKeyValidationTests(unittest.TestCase): """ Loading @@ -1088,7 +1076,7 @@ class CustomCacheKeyValidationTests(unittest.TestCase): """ def test_custom_key_validation(self): cache = get_cache('cache.liberal_backend://') cache = get_cache('cache.liberal_backend.CacheClass') # this key is both longer than 250 characters, and has spaces key = 'some key with spaces' * 15 Loading @@ -1100,10 +1088,6 @@ class CustomCacheKeyValidationTests(unittest.TestCase): class GetCacheTests(unittest.TestCase): def test_simple(self): cache = get_cache('locmem://') from django.core.cache.backends.locmem import LocMemCache self.assertIsInstance(cache, LocMemCache) from django.core.cache import cache self.assertIsInstance(cache, get_cache('default').__class__) Loading Loading
django/core/cache/__init__.py +20 −74 Original line number Diff line number Diff line Loading @@ -8,9 +8,9 @@ the abstract BaseCache class in django.core.cache.backends.base. Client code should not access a cache backend directly; instead it should either use the "cache" variable made available here, or it should use the get_cache() function made available here. get_cache() takes a backend URI (e.g. "memcached://127.0.0.1:11211/") and returns an instance of a backend cache class. get_cache() function made available here. get_cache() takes a CACHES alias or a backend path and config parameters, and returns an instance of a backend cache class. See docs/topics/cache.txt for information on the public API. """ Loading @@ -29,78 +29,17 @@ __all__ = [ 'get_cache', 'cache', 'DEFAULT_CACHE_ALIAS' ] # Name for use in settings file --> name of module in "backends" directory. # Any backend scheme that is not in this dictionary is treated as a Python # import path to a custom backend. BACKENDS = { 'memcached': 'memcached', 'locmem': 'locmem', 'file': 'filebased', 'db': 'db', 'dummy': 'dummy', } DEFAULT_CACHE_ALIAS = 'default' def parse_backend_uri(backend_uri): """ Converts the "backend_uri" into a cache scheme ('db', 'memcached', etc), a host and any extra params that are required for the backend. Returns a (scheme, host, params) tuple. """ if backend_uri.find(':') == -1: raise InvalidCacheBackendError("Backend URI must start with scheme://") scheme, rest = backend_uri.split(':', 1) if not rest.startswith('//'): raise InvalidCacheBackendError("Backend URI must start with scheme://") host = rest[2:] qpos = rest.find('?') if qpos != -1: params = dict(parse_qsl(rest[qpos+1:])) host = rest[2:qpos] else: params = {} if host.endswith('/'): host = host[:-1] return scheme, host, params if DEFAULT_CACHE_ALIAS not in settings.CACHES: raise ImproperlyConfigured("You must define a '%s' cache" % DEFAULT_CACHE_ALIAS) def parse_backend_conf(backend, **kwargs): """ Helper function to parse the backend configuration that doesn't use the URI notation. """ # Try to get the CACHES entry for the given backend name first conf = settings.CACHES.get(backend, None) if conf is not None: args = conf.copy() args.update(kwargs) backend = args.pop('BACKEND') location = args.pop('LOCATION', '') return backend, location, args else: try: # Trying to import the given backend, in case it's a dotted path import_by_path(backend) except ImproperlyConfigured as e: raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( backend, e)) location = kwargs.pop('LOCATION', '') return backend, location, kwargs def get_cache(backend, **kwargs): """ Function to load a cache backend dynamically. This is flexible by design to allow different use cases: To load a backend with the old URI-based notation:: cache = get_cache('locmem://') To load a backend that is pre-defined in the settings:: cache = get_cache('default') Loading @@ -114,16 +53,23 @@ def get_cache(backend, **kwargs): """ try: if '://' in backend: # for backwards compatibility backend, location, params = parse_backend_uri(backend) if backend in BACKENDS: backend = 'django.core.cache.backends.%s' % BACKENDS[backend] params.update(kwargs) mod = importlib.import_module(backend) backend_cls = mod.CacheClass # Try to get the CACHES entry for the given backend name first try: conf = settings.CACHES[backend] except KeyError: try: # Trying to import the given backend, in case it's a dotted path import_by_path(backend) except ImproperlyConfigured as e: raise InvalidCacheBackendError("Could not find backend '%s': %s" % ( backend, e)) location = kwargs.pop('LOCATION', '') params = kwargs else: backend, location, params = parse_backend_conf(backend, **kwargs) params = conf.copy() params.update(kwargs) backend = params.pop('BACKEND') location = params.pop('LOCATION', '') backend_cls = import_by_path(backend) except (AttributeError, ImportError, ImproperlyConfigured) as e: raise InvalidCacheBackendError( Loading
docs/releases/1.7.txt +4 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,10 @@ Miscellaneous Rationale behind this is removal of dependency of non-contrib code on contrib applications. * The old cache URI syntax (e.g. ``"locmem://"``) is no longer supported. It still worked, even though it was not documented or officially supported. If you're still using it, please update to the current :setting:`CACHES` syntax. Features deprecated in 1.7 ========================== Loading
tests/cache/tests.py +1 −17 Original line number Diff line number Diff line Loading @@ -857,10 +857,6 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): self.cache = get_cache(self.backend_name, LOCATION=self._table_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0}) self.perform_cull_test(50, 18) def test_old_initialization(self): self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name) self.perform_cull_test(50, 18) def test_second_call_doesnt_crash(self): with six.assertRaisesRegex(self, management.CommandError, "Cache table 'test cache table' could not be created"): Loading Loading @@ -956,10 +952,6 @@ class LocMemCacheTests(unittest.TestCase, BaseCacheTests): self.cache = get_cache(self.backend_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0}) self.perform_cull_test(50, 19) def test_old_initialization(self): self.cache = get_cache('locmem://?max_entries=30&cull_frequency=0') self.perform_cull_test(50, 19) def test_multiple_caches(self): "Check that multiple locmem caches are isolated" mirror_cache = get_cache(self.backend_name) Loading Loading @@ -1075,10 +1067,6 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests): def test_cull(self): self.perform_cull_test(50, 29) def test_old_initialization(self): self.cache = get_cache('file://%s?max_entries=30' % self.dirname) self.perform_cull_test(50, 29) class CustomCacheKeyValidationTests(unittest.TestCase): """ Loading @@ -1088,7 +1076,7 @@ class CustomCacheKeyValidationTests(unittest.TestCase): """ def test_custom_key_validation(self): cache = get_cache('cache.liberal_backend://') cache = get_cache('cache.liberal_backend.CacheClass') # this key is both longer than 250 characters, and has spaces key = 'some key with spaces' * 15 Loading @@ -1100,10 +1088,6 @@ class CustomCacheKeyValidationTests(unittest.TestCase): class GetCacheTests(unittest.TestCase): def test_simple(self): cache = get_cache('locmem://') from django.core.cache.backends.locmem import LocMemCache self.assertIsInstance(cache, LocMemCache) from django.core.cache import cache self.assertIsInstance(cache, get_cache('default').__class__) Loading