mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
Added a setup method hook for easier startup time code.
This commit is contained in:
parent
6596e191f0
commit
df865840bc
5 changed files with 77 additions and 16 deletions
|
|
@ -58,4 +58,6 @@ class Settings(six.with_metaclass(SettingsBase)):
|
|||
to the name of the class.
|
||||
|
||||
"""
|
||||
pass
|
||||
@classmethod
|
||||
def setup(cls):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -132,6 +132,22 @@ class SettingsImporter(object):
|
|||
return None
|
||||
|
||||
|
||||
def reraise(exc, prefix=None, suffix=None):
|
||||
args = exc.args
|
||||
if not args:
|
||||
args = ('',)
|
||||
if prefix is None:
|
||||
prefix = ''
|
||||
elif not prefix.endswith((':', ': ')):
|
||||
prefix = prefix + ': '
|
||||
if suffix is None:
|
||||
suffix = ''
|
||||
elif not (suffix.startswith('(') and suffix.endswith(')')):
|
||||
suffix = '(' + suffix + ')'
|
||||
exc.args = ('%s %s %s' % (prefix, exc.args[0], suffix),) + args[1:]
|
||||
raise
|
||||
|
||||
|
||||
class SettingsLoader(object):
|
||||
|
||||
def __init__(self, name, location):
|
||||
|
|
@ -143,31 +159,38 @@ class SettingsLoader(object):
|
|||
mod = sys.modules[fullname] # pragma: no cover
|
||||
else:
|
||||
mod = imp.load_module(fullname, *self.location)
|
||||
cls_path = '%s.%s' % (mod.__name__, self.name)
|
||||
try:
|
||||
cls = getattr(mod, self.name)
|
||||
except AttributeError: # pragma: no cover
|
||||
raise ImproperlyConfigured("Couldn't find settings '%s' in "
|
||||
"module '%s'" %
|
||||
(self.name, mod.__package__))
|
||||
except AttributeError as err: # pragma: no cover
|
||||
reraise(err,
|
||||
"While trying to find the '%s' settings in module '%s'" %
|
||||
(self.name, mod.__package__))
|
||||
try:
|
||||
cls.setup()
|
||||
except Exception as err:
|
||||
reraise(err, "While calling '%s.setup()'" % cls_path)
|
||||
try:
|
||||
obj = cls()
|
||||
except Exception as err:
|
||||
raise ImproperlyConfigured("Couldn't load settings '%s.%s': %s" %
|
||||
(mod.__name__, self.name, err))
|
||||
reraise(err,
|
||||
"While loading the '%s' settings" % cls_path)
|
||||
|
||||
try:
|
||||
attributes = uppercase_attributes(obj).items()
|
||||
except Exception as err:
|
||||
raise ImproperlyConfigured("Couldn't get items of settings "
|
||||
"'%s.%s': %s" %
|
||||
(mod.__name__, self.name, err))
|
||||
reraise(err,
|
||||
"While getting the items of the '%s' settings" %
|
||||
cls_path)
|
||||
|
||||
for name, value in attributes:
|
||||
if callable(value) and not getattr(value, 'pristine', False):
|
||||
try:
|
||||
value = value()
|
||||
except Exception as err:
|
||||
raise ImproperlyConfigured(
|
||||
"Couldn't call '%s' in '%s.%s': %s" %
|
||||
(value, mod.__name__, self.name, err))
|
||||
reraise(err,
|
||||
"While calling '%s.%s'" % (cls_path, value))
|
||||
setattr(mod, name, value)
|
||||
|
||||
setattr(mod, 'CONFIGURATION', '%s.%s' % (fullname, self.name))
|
||||
return mod
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ class Test(Settings):
|
|||
|
||||
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
||||
|
||||
def TEMPLATE_CONTEXT_PROCESSORS(self):
|
||||
return Settings.TEMPLATE_CONTEXT_PROCESSORS + (
|
||||
'configurations.tests.settings.base.test_callback',)
|
||||
|
||||
ATTRIBUTE_SETTING = True
|
||||
|
||||
_PRIVATE_SETTING = 'ryan'
|
||||
|
|
@ -49,6 +53,6 @@ class Test(Settings):
|
|||
def PRISTINE_FUNCTION_SETTING():
|
||||
return 5
|
||||
|
||||
def TEMPLATE_CONTEXT_PROCESSORS(self):
|
||||
return Settings.TEMPLATE_CONTEXT_PROCESSORS + (
|
||||
'configurations.tests.settings.base.test_callback',)
|
||||
@classmethod
|
||||
def setup(cls):
|
||||
cls.SETUP_TEST_SETTING = 6
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class MainTests(TestCase):
|
|||
global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
|
||||
'configurations.tests.settings.base.test_callback',
|
||||
))
|
||||
self.assertEqual(main.SETUP_TEST_SETTING, 6)
|
||||
|
||||
def test_global_arrival(self):
|
||||
from django.conf import settings
|
||||
|
|
@ -34,6 +35,7 @@ class MainTests(TestCase):
|
|||
self.assertTrue(lambda: callable(settings.PRISTINE_LAMBDA_SETTING))
|
||||
self.assertNotEqual(settings.PRISTINE_FUNCTION_SETTING, 5)
|
||||
self.assertTrue(lambda: callable(settings.PRISTINE_FUNCTION_SETTING))
|
||||
self.assertEqual(settings.SETUP_TEST_SETTING, 6)
|
||||
|
||||
@patch.dict(os.environ, clear=True, DJANGO_CONFIGURATION='Test')
|
||||
def test_empty_module_var(self):
|
||||
|
|
|
|||
|
|
@ -155,6 +155,36 @@ Lambdas work, too::
|
|||
class Prod(Settings):
|
||||
ACCESS_FUNCTION = pristine(lamda user: user.is_staff)
|
||||
|
||||
Setup methods
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 0.3
|
||||
|
||||
If there is something required to be set up after all the settings have been
|
||||
loaded please override the ``setup`` class method like so (don't forget
|
||||
to apply the Python ``@classmethod`` decorator::
|
||||
|
||||
from configurations import Settings
|
||||
|
||||
class Prod(Settings):
|
||||
# ...
|
||||
|
||||
@classmethod
|
||||
def setup(cls):
|
||||
if something.completely.different():
|
||||
cls.DEBUG = True
|
||||
|
||||
Or do something unrelated to your settings, like connecting to a database::
|
||||
|
||||
from configurations import Settings
|
||||
|
||||
class Prod(Settings):
|
||||
# ...
|
||||
|
||||
@classmethod
|
||||
def setup(cls):
|
||||
import mango
|
||||
mango.connect('enterprise')
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue