| 1 |
""" |
|---|
| 2 |
Caching framework. |
|---|
| 3 |
|
|---|
| 4 |
This package defines set of cache backends that all conform to a simple API. |
|---|
| 5 |
In a nutshell, a cache is a set of values -- which can be any object that |
|---|
| 6 |
may be pickled -- identified by string keys. For the complete API, see |
|---|
| 7 |
the abstract BaseCache class in django.core.cache.backends.base. |
|---|
| 8 |
|
|---|
| 9 |
Client code should not access a cache backend directly; instead it should |
|---|
| 10 |
either use the "cache" variable made available here, or it should use the |
|---|
| 11 |
get_cache() function made available here. get_cache() takes a backend URI |
|---|
| 12 |
(e.g. "memcached://127.0.0.1:11211/") and returns an instance of a backend |
|---|
| 13 |
cache class. |
|---|
| 14 |
|
|---|
| 15 |
See docs/cache.txt for information on the public API. |
|---|
| 16 |
""" |
|---|
| 17 |
|
|---|
| 18 |
from cgi import parse_qsl |
|---|
| 19 |
from django.conf import settings |
|---|
| 20 |
from django.core import signals |
|---|
| 21 |
from django.core.cache.backends.base import InvalidCacheBackendError |
|---|
| 22 |
|
|---|
| 23 |
# Name for use in settings file --> name of module in "backends" directory. |
|---|
| 24 |
# Any backend scheme that is not in this dictionary is treated as a Python |
|---|
| 25 |
# import path to a custom backend. |
|---|
| 26 |
BACKENDS = { |
|---|
| 27 |
'memcached': 'memcached', |
|---|
| 28 |
'locmem': 'locmem', |
|---|
| 29 |
'file': 'filebased', |
|---|
| 30 |
'db': 'db', |
|---|
| 31 |
'dummy': 'dummy', |
|---|
| 32 |
} |
|---|
| 33 |
|
|---|
| 34 |
def get_cache(backend_uri): |
|---|
| 35 |
if backend_uri.find(':') == -1: |
|---|
| 36 |
raise InvalidCacheBackendError, "Backend URI must start with scheme://" |
|---|
| 37 |
scheme, rest = backend_uri.split(':', 1) |
|---|
| 38 |
if not rest.startswith('//'): |
|---|
| 39 |
raise InvalidCacheBackendError, "Backend URI must start with scheme://" |
|---|
| 40 |
|
|---|
| 41 |
host = rest[2:] |
|---|
| 42 |
qpos = rest.find('?') |
|---|
| 43 |
if qpos != -1: |
|---|
| 44 |
params = dict(parse_qsl(rest[qpos+1:])) |
|---|
| 45 |
host = rest[2:qpos] |
|---|
| 46 |
else: |
|---|
| 47 |
params = {} |
|---|
| 48 |
if host.endswith('/'): |
|---|
| 49 |
host = host[:-1] |
|---|
| 50 |
|
|---|
| 51 |
if scheme in BACKENDS: |
|---|
| 52 |
module = __import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, ['']) |
|---|
| 53 |
else: |
|---|
| 54 |
module = __import__(scheme, {}, {}, ['']) |
|---|
| 55 |
return getattr(module, 'CacheClass')(host, params) |
|---|
| 56 |
|
|---|
| 57 |
cache = get_cache(settings.CACHE_BACKEND) |
|---|
| 58 |
|
|---|
| 59 |
# Some caches -- pythont-memcached in particular -- need to do a cleanup at the |
|---|
| 60 |
# end of a request cycle. If the cache provides a close() method, wire it up |
|---|
| 61 |
# here. |
|---|
| 62 |
if hasattr(cache, 'close'): |
|---|
| 63 |
signals.request_finished.connect(cache.close) |
|---|