diff --git a/constance/admin.py b/constance/admin.py index b9ca7ac..dcc9b2d 100644 --- a/constance/admin.py +++ b/constance/admin.py @@ -61,8 +61,13 @@ class ConstanceAdmin(admin.ModelAdmin): @csrf_protect_m def changelist_view(self, request, extra_context=None): - form = ConstanceForm(initial=dict((name, getattr(config, name)) - for name in settings.CONFIG)) + # First load a mapping between config name and default value + default_initial = ((name, default) + for name, (default, help_text) in settings.CONFIG.iteritems()) + # Then update the mapping with actually values from the backend + initial = dict(default_initial, + **dict(config._backend.mget(settings.CONFIG.iterkeys()))) + form = ConstanceForm(initial=initial) if request.method == 'POST': form = ConstanceForm(request.POST) if form.is_valid(): @@ -79,7 +84,11 @@ class ConstanceAdmin(admin.ModelAdmin): 'media': self.media + form.media, } for name, (default, help_text) in settings.CONFIG.iteritems(): - value = getattr(config, name) + # First try to load the value from the actual backend + value = initial.get(name) + # Then if the returned value is None, get the default + if value is None: + value = getattr(config, name) context['config'].append({ 'name': name, 'default': localize(default), diff --git a/constance/backends/__init__.py b/constance/backends/__init__.py index 1eb0a02..a7f9f40 100644 --- a/constance/backends/__init__.py +++ b/constance/backends/__init__.py @@ -1,16 +1,25 @@ +""" +Defines the base constance backend +""" class Backend(object): def get(self, key): """ - Get the key from the backend store and return it. + Get the key from the backend store and return the value. Return None if not found. """ raise NotImplementedError + def mget(self, keys): + """ + Get the keys from the backend store and return a list of the values. + Return an empty list if not found. + """ + raise NotImplementedError + def set(self, key, value): """ Add the value to the backend store given the key. """ raise NotImplementedError - diff --git a/constance/backends/redisd.py b/constance/backends/redisd.py index cf09b12..d70c4a5 100644 --- a/constance/backends/redisd.py +++ b/constance/backends/redisd.py @@ -1,3 +1,5 @@ +import itertools + from django.core.exceptions import ImproperlyConfigured from constance import settings, utils @@ -34,5 +36,10 @@ class RedisBackend(Backend): return loads(value) return None + def mget(self, keys): + prefixed_keys = (self.add_prefix(key) for key in keys) + values = (loads(value) for value in self._rd.mget(prefixed_keys)) + return itertools.izip(keys, values) + def set(self, key, value): self._rd.set(self.add_prefix(key), dumps(value)) diff --git a/tests/testproject/test_app/redis_mockup.py b/tests/testproject/test_app/redis_mockup.py index 0af0017..5b0778b 100644 --- a/tests/testproject/test_app/redis_mockup.py +++ b/tests/testproject/test_app/redis_mockup.py @@ -2,4 +2,10 @@ class Connection(dict): def set(self, key, value): self[key] = value - + def mget(self, keys): + values = [] + for key in keys: + value = self.get(key, None) + if value is not None: + values.append(value) + return values