import warnings from django.utils import six from django.conf import global_settings from django.core.exceptions import ImproperlyConfigured from .utils import uppercase_attributes from .values import Value, setup_value __all__ = ['Configuration'] install_failure = ("django-configurations settings importer wasn't " "correctly installed. Please use one of the starter " "functions to install it as mentioned in the docs: " "http://django-configurations.readthedocs.org/") class ConfigurationBase(type): def __new__(cls, name, bases, attrs): # also check for "Configuration" here to handle the Settings class # below remove it when we deprecate the Settings class if (bases not in ((object,), ()) and bases[0].__name__ not in ('NewBase', 'Configuration')): # if this is actually a subclass in a settings module # we better check if the importer was correctly installed from . import importer if not importer.installed: raise ImproperlyConfigured(install_failure) settings_vars = uppercase_attributes(global_settings) parents = [base for base in bases if isinstance(base, ConfigurationBase)] if parents: for base in bases[::-1]: settings_vars.update(uppercase_attributes(base)) attrs = dict(settings_vars, **attrs) return super(ConfigurationBase, cls).__new__(cls, name, bases, attrs) def __repr__(self): return "".format(self.__module__, self.__name__) class Configuration(six.with_metaclass(ConfigurationBase)): """ The base configuration class to inherit from. :: class Develop(Configuration): EXTRA_AWESOME = True @property def SOMETHING(self): return completely.different() def OTHER(self): if whatever: return (1, 2, 3) return (4, 5, 6) The module this configuration class is located in will automatically get the class and instance level attributes with upper characters if the ``DJANGO_CONFIGURATION`` is set to the name of the class. """ @classmethod def pre_setup(cls): pass @classmethod def post_setup(cls): pass @classmethod def setup(cls): for name, value in uppercase_attributes(cls).items(): if isinstance(value, Value): setup_value(cls, name, value) class Settings(Configuration): @classmethod def pre_setup(cls): # make sure to remove the handling of the Settings class above when deprecating warnings.warn("configurations.Settings was renamed to " "settings.Configuration and will be " "removed in 1.0", PendingDeprecationWarning)