Ticket #1371: appsettings.py

File appsettings.py, 3.1 KB (added by shai, 6 years ago)

helper module for defining application settings objects

Line 
1from django.utils.functional import memoize
2from django.core.exceptions import ImproperlyConfigured
3
4__all__ = ['RequiredSetting', 'FromSetting', 'ComputedSetting', 'AppSettings']
5
6class SpecialConf(object):
7    """
8    Base for classes defining special configuration options
9    The interface is simple: get_value(name) will be called if
10    no value was supplied for the setting by the user
11    """
12    def get_value(self, name):
13        raise NotImplementedError
14   
15    def set_settings_object(self, obj):
16        self.settings_object = obj
17   
18class RequiredSetting(SpecialConf):
19    "Just to mark a setting as required"
20    def get_value(self, name):
21        raise ImproperlyConfigured, "%s setting is missing" % name
22   
23class FromSetting(SpecialConf):
24    "Take default value from another setting"
25    def __init__(self, source):
26        self.source = source
27    def get_value(self, name):
28        return getattr(self.settings_object, self.source)
29   
30class ComputedSetting(SpecialConf):
31    """
32    Compute default from a set of other settings.
33   
34    Initialized with a function, a sequence of settings names, and optional
35    additional (constant) arguments and keyword arguments. The default for
36    the setting will be computed (only if needed) by calling the function
37    with the setting values as first positional arguments, followed by
38     
39    """
40    def __init__(self, func, sources, *args, **kwargs):
41        self.func = func
42        if isinstance(sources, basestring): sources = (sources,)
43        self.sources = sources
44        self.args = args
45        self.kwargs = kwargs
46    def get_value(self, name):
47        sources = [getattr(self.settings_object, s) for s in self.sources]
48        sources.extend(self.args)
49        return self.func(*sources, **self.kwargs)
50       
51
52
53class SettingProperty(object):
54   
55    def __init__(self, name, default, cache):
56        self.name = name
57        self.default = default
58        self.getter = memoize(self.get_conf_value, cache, 1)
59       
60    def __get__(self, settings_object, type=None):
61        return self.getter(self.name, self.default, settings_object)
62
63    @staticmethod
64    def get_conf_value(name, default, settings_object):
65        # First look in the project settings file
66        from django.conf import settings
67        value = getattr(settings, name, default)
68        if isinstance(value, SpecialConf):
69            # Special settings may want to use other settings from the settings_object
70            value.set_settings_object(settings_object)
71            value = value.get_value(name)
72        return value
73   
74class SettingsMetaClass(type):
75   
76    def __new__(meta, name, bases, namespace):
77        # turn all all-caps names into settings
78        cache = {}
79        for n, v in namespace.items():
80            if n==n.upper():
81                namespace[n] = SettingProperty(n, v, cache)
82        return super(SettingsMetaClass, meta).__new__(meta, name, bases, namespace)
83 
84class AppSettings(object):
85 
86    __metaclass__ = SettingsMetaClass
87
88    def __getattr__(self, name):
89        # for names not in our class
90        from django.conf import settings
91        return getattr(settings, name)
92       
Back to Top