diff --git a/constance/admin.py b/constance/admin.py index 94ac72b..a365509 100644 --- a/constance/admin.py +++ b/constance/admin.py @@ -85,9 +85,9 @@ class ConstanceForm(forms.Form): for name, options in settings.CONFIG.items(): default, help_text = options[0], options[1] if len(options) == 3: - config_type = options[2] + config_type = options[2] else: - config_type = type(default) + config_type = type(default) if config_type not in FIELDS: raise ImproperlyConfigured(_("Constance doesn't support " @@ -134,6 +134,24 @@ class ConstanceAdmin(admin.ModelAdmin): name='%s_%s_add' % info), ] + def get_config_value(self, name, options, form, initial): + default, help_text = options[0], options[1] + # 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) + config_value = { + 'name': name, + 'default': localize(default), + 'help_text': _(help_text), + 'value': localize(value), + 'modified': value != default, + 'form_field': form[name], + } + + return config_value + @csrf_protect_m def changelist_view(self, request, extra_context=None): # First load a mapping between config name and default value @@ -160,26 +178,30 @@ class ConstanceAdmin(admin.ModelAdmin): 'config_values': [], 'title': _('Constance config'), 'app_label': 'constance', - 'opts': Config._meta, + 'opts': self.model._meta, 'form': form, 'media': self.media + form.media, 'icon_type': 'gif' if VERSION < (1, 9) else 'svg', } for name, options in settings.CONFIG.items(): - default, help_text = options[0], options[1] - # 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_values'].append({ - 'name': name, - 'default': localize(default), - 'help_text': _(help_text), - 'value': localize(value), - 'modified': value != default, - 'form_field': form[name], - }) + context['config_values'].append(self.get_config_value(name, options, form, initial)) + + if settings.CONFIG_FIELDSETS: + context['fieldsets'] = [] + for fieldset_title, fields_list in settings.CONFIG_FIELDSETS.items(): + fields_exist = all(field in settings.CONFIG.keys() for field in fields_list) + assert fields_exist, "CONSTANCE_CONFIG_FIELDSETS contains fields that does not exist" + config_values = [] + + for name, options in settings.CONFIG.items(): + if name in fields_list: + config_values.append(self.get_config_value(name, options, form, initial)) + + context['fieldsets'].append({ + 'title': fieldset_title, + 'config_values': config_values + }) + context['config_values'].sort(key=itemgetter('name')) request.current_app = self.admin_site.name # compatibility to be removed when 1.7 is deprecated diff --git a/constance/settings.py b/constance/settings.py index 85cc373..716a103 100644 --- a/constance/settings.py +++ b/constance/settings.py @@ -5,6 +5,8 @@ BACKEND = getattr(settings, 'CONSTANCE_BACKEND', CONFIG = getattr(settings, 'CONSTANCE_CONFIG', {}) +CONFIG_FIELDSETS = getattr(settings, 'CONSTANCE_CONFIG_FIELDSETS', {}) + ADDITIONAL_FIELDS = getattr(settings, 'CONSTANCE_ADDITIONAL_FIELDS', {}) DATABASE_CACHE_BACKEND = getattr(settings, 'CONSTANCE_DATABASE_CACHE_BACKEND', diff --git a/constance/templates/admin/constance/change_list.html b/constance/templates/admin/constance/change_list.html index a40dba4..2902bb1 100644 --- a/constance/templates/admin/constance/change_list.html +++ b/constance/templates/admin/constance/change_list.html @@ -51,37 +51,18 @@ {% if form.errors %} {% endif %} - - - - - - - - - - {% for item in config_values %} - - - - - - - {% endfor %} -
{% trans "Name" %}
{% trans "Default" %}
{% trans "Value" %}
{% trans "Is modified" %}
{{ item.name }} -
{{ item.help_text|linebreaksbr }}
-
- {{ item.default }} - - {{ item.form_field.errors }} - {{ item.form_field }} - - {% if item.modified %} - {{ item.modified }} - {% else %} - {{ item.modified }} - {% endif %} -
+ + {% if fieldsets %} + {% for fieldset in fieldsets %} +

{{ fieldset.title }}

+ {% with config_values=fieldset.config_values %} + {% include "admin/constance/includes/results_list.html" %} + {% endwith %} + {% endfor %} + {% else %} + {% include "admin/constance/includes/results_list.html" %} + {% endif %} +

diff --git a/constance/templates/admin/constance/includes/results_list.html b/constance/templates/admin/constance/includes/results_list.html new file mode 100644 index 0000000..02043fd --- /dev/null +++ b/constance/templates/admin/constance/includes/results_list.html @@ -0,0 +1,32 @@ +{% load admin_static admin_list i18n %} + + + + + + + + + + {% for item in config_values %} + + + + + + + {% endfor %} +
{% trans "Name" %}
{% trans "Default" %}
{% trans "Value" %}
{% trans "Is modified" %}
{{ item.name }} +
{{ item.help_text|linebreaksbr }}
+
+ {{ item.default }} + + {{ item.form_field.errors }} + {{ item.form_field }} + + {% if item.modified %} + {{ item.modified }} + {% else %} + {{ item.modified }} + {% endif %} +
\ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index da5ff03..71fec82 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -118,6 +118,25 @@ Note: Use later evaluated strings instead of direct classes for the field and wi 'MY_SELECT_KEY': ('yes', 'select yes or no', 'yes_no_null_select'), } +Fieldsets +------------- + +To group settings together you can define fieldsets. Here's an example: + +.. code-block:: python + + CONSTANCE_CONFIG = { + 'SITE_NAME': ('My Title', 'Website title'), + 'SITE_DESCRIPTION': ('', 'Website description'), + 'THEME': ('light-blue', 'Website theme'), + } + + CONSTANCE_CONFIG_FIELDSETS = { + 'General Options': ('SITE_NAME', 'SITE_DESCRIPTION'), + 'Theme Options': ('THEME',), + } +.. image:: screenshot3.png + Usage ----- diff --git a/docs/screenshot3.png b/docs/screenshot3.png new file mode 100644 index 0000000..3cd6ddc Binary files /dev/null and b/docs/screenshot3.png differ