diff --git a/constance/admin.py b/constance/admin.py index 3b564e7..b61912f 100644 --- a/constance/admin.py +++ b/constance/admin.py @@ -1,5 +1,6 @@ from datetime import datetime, date, time from decimal import Decimal +import hashlib from operator import itemgetter import six @@ -13,7 +14,12 @@ from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from django.template.context import RequestContext from django.utils.formats import localize -from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_lazy as _ + +try: + from django.utils.encoding import smart_bytes +except ImportError: + from django.utils.encoding import smart_str as smart_bytes try: from django.conf.urls import patterns, url @@ -54,22 +60,37 @@ if not six.PY3: class ConstanceForm(forms.Form): - def __init__(self, *args, **kwargs): - super(ConstanceForm, self).__init__(*args, **kwargs) + version = forms.CharField(widget=forms.HiddenInput) + + def __init__(self, initial, *args, **kwargs): + super(ConstanceForm, self).__init__(*args, initial=initial, **kwargs) + version_hash = hashlib.md5() + for name, (default, help_text) in settings.CONFIG.items(): config_type = type(default) if config_type not in FIELDS: - raise ImproperlyConfigured("Constance doesn't support " - "config values of the type %s. " - "Please fix the value of '%s'." + raise ImproperlyConfigured(_("Constance doesn't support " + "config values of the type %s. " + "Please fix the value of '%s'.") % (config_type, name)) field_class, kwargs = FIELDS[config_type] self.fields[name] = field_class(label=name, **kwargs) + version_hash.update(smart_bytes(initial.get(name, ''))) + self.initial['version'] = version_hash.hexdigest() + def save(self): - for name in self.cleaned_data: + for name in settings.CONFIG: setattr(config, name, self.cleaned_data[name]) + def clean_version(self): + value = self.cleaned_data['version'] + if value != self.initial['version']: + raise forms.ValidationError(_('The settings have been modified ' + 'by someone else. Please reload the ' + 'form and resubmit your changes.')) + return value + class ConstanceAdmin(admin.ModelAdmin): @@ -96,7 +117,7 @@ class ConstanceAdmin(admin.ModelAdmin): **dict(config._backend.mget(settings.CONFIG.keys()))) form = ConstanceForm(initial=initial) if request.method == 'POST': - form = ConstanceForm(request.POST) + form = ConstanceForm(data=request.POST, initial=initial) if form.is_valid(): form.save() # In django 1.5 this can be replaced with self.message_user diff --git a/constance/templates/admin/constance/change_list.html b/constance/templates/admin/constance/change_list.html index e09b0f5..bd1aea3 100644 --- a/constance/templates/admin/constance/change_list.html +++ b/constance/templates/admin/constance/change_list.html @@ -36,6 +36,14 @@
{% csrf_token %} +
    + {% for field in form.hidden_fields %} + {% for error in field.errors %} +
  • {{ error }}
  • + {% endfor %} + {{ field }} + {% endfor %} +
@@ -47,15 +55,15 @@ {% for item in config %} -
{{item.name}} -
{{item.help_text}}
+
{{ item.name }} +
{{ item.help_text }}
{{ item.default }} - {{item.form_field.errors}} - {{item.form_field}} + {{ item.form_field.errors }} + {{ item.form_field }} {% if item.modified %}