from __future__ import annotations from django.core import checks from django.core.checks import CheckMessage from django.utils.translation import gettext_lazy as _ def check_fieldsets(*args, **kwargs) -> list[CheckMessage]: """ A Django system check to make sure that, if defined, CONFIG_FIELDSETS is consistent with settings.CONFIG. """ from . import settings errors = [] if hasattr(settings, "CONFIG_FIELDSETS") and settings.CONFIG_FIELDSETS: missing_keys, extra_keys = get_inconsistent_fieldnames() if missing_keys: check = checks.Warning( _("CONSTANCE_CONFIG_FIELDSETS is missing field(s) that exists in CONSTANCE_CONFIG."), hint=", ".join(sorted(missing_keys)), obj="settings.CONSTANCE_CONFIG", id="constance.E001", ) errors.append(check) if extra_keys: check = checks.Warning( _("CONSTANCE_CONFIG_FIELDSETS contains extra field(s) that does not exist in CONFIG."), hint=", ".join(sorted(extra_keys)), obj="settings.CONSTANCE_CONFIG", id="constance.E002", ) errors.append(check) return errors def get_inconsistent_fieldnames() -> tuple[set, set]: """ Returns a pair of values: 1) set of keys from settings.CONFIG that are not accounted for in settings.CONFIG_FIELDSETS 2) set of keys from settings.CONFIG_FIELDSETS that are not present in settings.CONFIG If there are no fieldnames in settings.CONFIG_FIELDSETS, returns an empty set. """ from . import settings if isinstance(settings.CONFIG_FIELDSETS, dict): fieldset_items = settings.CONFIG_FIELDSETS.items() else: fieldset_items = settings.CONFIG_FIELDSETS unique_field_names = set() for _fieldset_title, fields_list in fieldset_items: # fields_list can be a dictionary, when a fieldset is defined as collapsible # https://django-constance.readthedocs.io/en/latest/#fieldsets-collapsing if isinstance(fields_list, dict) and "fields" in fields_list: fields_list = fields_list["fields"] unique_field_names.update(fields_list) if not unique_field_names: return unique_field_names, unique_field_names config_keys = set(settings.CONFIG.keys()) missing_keys = config_keys - unique_field_names extra_keys = unique_field_names - config_keys return missing_keys, extra_keys