mirror of
https://github.com/jazzband/django-constance.git
synced 2026-03-16 22:40:24 +00:00
parent
16bb8d50e6
commit
8b0ed361d6
6 changed files with 72 additions and 29 deletions
29
README.rst
29
README.rst
|
|
@ -125,17 +125,9 @@ you need to install this library, too. E.g.::
|
||||||
Alternatively follow the backend specific installation instructions above.
|
Alternatively follow the backend specific installation instructions above.
|
||||||
|
|
||||||
The database backend has the ability to automatically cache the config
|
The database backend has the ability to automatically cache the config
|
||||||
values and clear them when saving. You need to set the following setting
|
values and clear them when saving. Assuming you have a ``CACHES`` setting set
|
||||||
to enable this feature::
|
you need to set the the ``CONSTANCE_DATABASE_CACHE_BACKEND`` setting to enable
|
||||||
|
this feature::
|
||||||
CONSTANCE_DATABASE_CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
|
|
||||||
|
|
||||||
.. note:: This won't work with a cache backend that doesn't support
|
|
||||||
cross-process caching, because correct cache invalidation
|
|
||||||
can't be guaranteed.
|
|
||||||
|
|
||||||
Starting in Django 1.3 you can alternatively use the name of an entry of
|
|
||||||
the ``CACHES`` setting. E.g.::
|
|
||||||
|
|
||||||
CACHES = {
|
CACHES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
|
@ -145,6 +137,14 @@ the ``CACHES`` setting. E.g.::
|
||||||
}
|
}
|
||||||
CONSTANCE_DATABASE_CACHE_BACKEND = 'default'
|
CONSTANCE_DATABASE_CACHE_BACKEND = 'default'
|
||||||
|
|
||||||
|
.. note:: This won't work with a cache backend that doesn't support
|
||||||
|
cross-process caching, because correct cache invalidation
|
||||||
|
can't be guaranteed.
|
||||||
|
|
||||||
|
.. note:: By default Constance will autofill the cache on startup and after
|
||||||
|
saving any of the config values. If you want to disable the cache simply
|
||||||
|
set the ``CONSTANCE_DATABASE_CACHE_AUTOFILL_TIMEOUT`` setting to ``None``.
|
||||||
|
|
||||||
Just like the Redis backend you can set an optional prefix that is used during
|
Just like the Redis backend you can set an optional prefix that is used during
|
||||||
database interactions. To keep backward compatibility it defaults to ``''``
|
database interactions. To keep backward compatibility it defaults to ``''``
|
||||||
(an empty string). To use something else do this::
|
(an empty string). To use something else do this::
|
||||||
|
|
@ -229,6 +229,13 @@ Screenshots
|
||||||
Changelog
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
v1.0 (unreleased)
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Added new autofill feature for the database backend cache which is enabled
|
||||||
|
by default.
|
||||||
|
|
||||||
|
|
||||||
v0.6 (2013/04/12)
|
v0.6 (2013/04/12)
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from constance.config import Config
|
from constance.config import Config
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig # noqa
|
||||||
except ImportError:
|
except ImportError:
|
||||||
config = Config()
|
config = Config()
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ from django.apps import AppConfig
|
||||||
from constance.config import Config
|
from constance.config import Config
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class ConstanceConfig(AppConfig):
|
class ConstanceConfig(AppConfig):
|
||||||
name = 'constance'
|
name = 'constance'
|
||||||
verbose_name = _('Constance')
|
verbose_name = _('Constance')
|
||||||
|
|
|
||||||
|
|
@ -10,32 +10,49 @@ except ImportError:
|
||||||
from constance.backends import Backend
|
from constance.backends import Backend
|
||||||
from constance import settings
|
from constance import settings
|
||||||
|
|
||||||
db_cache = None
|
|
||||||
if settings.DATABASE_CACHE_BACKEND:
|
|
||||||
db_cache = get_cache(settings.DATABASE_CACHE_BACKEND)
|
|
||||||
if isinstance(db_cache, LocMemCache):
|
|
||||||
raise ImproperlyConfigured(
|
|
||||||
"The CONSTANCE_DATABASE_CACHE_BACKEND setting refers to a "
|
|
||||||
"subclass of Django's local-memory backend (%r). Please set "
|
|
||||||
"it to a backend that supports cross-process caching."
|
|
||||||
% settings.DATABASE_CACHE_BACKEND)
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseBackend(Backend):
|
class DatabaseBackend(Backend):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
from constance.backends.database.models import Constance
|
from constance.backends.database.models import Constance
|
||||||
self._model = Constance
|
self._model = Constance
|
||||||
self._prefix = settings.DATABASE_PREFIX
|
self._prefix = settings.DATABASE_PREFIX
|
||||||
|
self._autofill_timeout = settings.DATABASE_CACHE_AUTOFILL_TIMEOUT
|
||||||
|
self._autofill_cachekey = 'autofilled'
|
||||||
|
|
||||||
if not self._model._meta.installed:
|
if not self._model._meta.installed:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
"The constance.backends.database app isn't installed "
|
"The constance.backends.database app isn't installed "
|
||||||
"correctly. Make sure it's in your INSTALLED_APPS setting.")
|
"correctly. Make sure it's in your INSTALLED_APPS setting.")
|
||||||
|
|
||||||
|
if settings.DATABASE_CACHE_BACKEND:
|
||||||
|
self._cache = get_cache(settings.DATABASE_CACHE_BACKEND)
|
||||||
|
if isinstance(self._cache, LocMemCache):
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"The CONSTANCE_DATABASE_CACHE_BACKEND setting refers to a "
|
||||||
|
"subclass of Django's local-memory backend (%r). Please set "
|
||||||
|
"it to a backend that supports cross-process caching."
|
||||||
|
% settings.DATABASE_CACHE_BACKEND)
|
||||||
|
else:
|
||||||
|
self._cache = None
|
||||||
|
self.autofill()
|
||||||
# Clear simple cache.
|
# Clear simple cache.
|
||||||
post_save.connect(self.clear, sender=self._model)
|
post_save.connect(self.clear, sender=self._model)
|
||||||
|
|
||||||
def add_prefix(self, key):
|
def add_prefix(self, key):
|
||||||
return "%s%s" % (self._prefix, key)
|
return "%s%s" % (self._prefix, key)
|
||||||
|
|
||||||
|
def autofill(self):
|
||||||
|
if not self._autofill_timeout or not self._cache:
|
||||||
|
return
|
||||||
|
full_cachekey = self.add_prefix(self._autofill_cachekey)
|
||||||
|
if self._cache.get(full_cachekey):
|
||||||
|
return
|
||||||
|
autofill_values = {}
|
||||||
|
autofill_values[full_cachekey] = 1
|
||||||
|
for key, value in self.mget(settings.CONFIG.keys()):
|
||||||
|
autofill_values[self.add_prefix(key)] = value
|
||||||
|
self._cache.set_many(autofill_values, timeout=self._autofill_timeout)
|
||||||
|
|
||||||
def mget(self, keys):
|
def mget(self, keys):
|
||||||
if not keys:
|
if not keys:
|
||||||
return
|
return
|
||||||
|
|
@ -46,17 +63,18 @@ class DatabaseBackend(Backend):
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
key = self.add_prefix(key)
|
key = self.add_prefix(key)
|
||||||
value = None
|
if self._cache:
|
||||||
if db_cache:
|
value = self._cache.get(key)
|
||||||
value = db_cache.get(key)
|
else:
|
||||||
|
value = None
|
||||||
if value is None:
|
if value is None:
|
||||||
try:
|
try:
|
||||||
value = self._model._default_manager.get(key=key).value
|
value = self._model._default_manager.get(key=key).value
|
||||||
except self._model.DoesNotExist:
|
except self._model.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if db_cache:
|
if self._cache:
|
||||||
db_cache.add(key, value)
|
self._cache.add(key, value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def set(self, key, value):
|
def set(self, key, value):
|
||||||
|
|
@ -68,5 +86,9 @@ class DatabaseBackend(Backend):
|
||||||
constance.save()
|
constance.save()
|
||||||
|
|
||||||
def clear(self, sender, instance, created, **kwargs):
|
def clear(self, sender, instance, created, **kwargs):
|
||||||
if db_cache and not created:
|
if self._cache and not created:
|
||||||
db_cache.delete_many(self.add_prefix(k) for k in settings.CONFIG.keys())
|
keys = [self.add_prefix(k)
|
||||||
|
for k in settings.CONFIG.keys()]
|
||||||
|
keys.append(self.add_prefix(self._autofill_cachekey))
|
||||||
|
self._cache.delete_many(keys)
|
||||||
|
self.autofill()
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ REDIS_CONNECTION = getattr(settings, 'CONSTANCE_REDIS_CONNECTION',
|
||||||
DATABASE_CACHE_BACKEND = getattr(settings, 'CONSTANCE_DATABASE_CACHE_BACKEND',
|
DATABASE_CACHE_BACKEND = getattr(settings, 'CONSTANCE_DATABASE_CACHE_BACKEND',
|
||||||
None)
|
None)
|
||||||
|
|
||||||
|
DATABASE_CACHE_AUTOFILL_TIMEOUT = getattr(settings,
|
||||||
|
'CONSTANCE_DATABASE_CACHE_AUTOFILL_TIMEOUT',
|
||||||
|
60 * 60 * 24)
|
||||||
|
|
||||||
DATABASE_PREFIX = getattr(settings, 'CONSTANCE_DATABASE_PREFIX', '')
|
DATABASE_PREFIX = getattr(settings, 'CONSTANCE_DATABASE_PREFIX', '')
|
||||||
|
|
||||||
SUPERUSER_ONLY = getattr(settings, 'CONSTANCE_SUPERUSER_ONLY', True)
|
SUPERUSER_ONLY = getattr(settings, 'CONSTANCE_SUPERUSER_ONLY', True)
|
||||||
|
|
|
||||||
|
|
@ -116,3 +116,12 @@ CONSTANCE_CONFIG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
|
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
|
||||||
|
|
||||||
|
|
||||||
|
CACHES = {
|
||||||
|
'default': {
|
||||||
|
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||||
|
'LOCATION': '127.0.0.1:11211',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CONSTANCE_DATABASE_CACHE_BACKEND = 'default'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue