Extended the setup methods in pre and post phase. Fixes #27.

This commit is contained in:
Jannis Leidel 2013-05-15 11:32:57 +02:00
parent d4da16273a
commit bebe4f254b
5 changed files with 57 additions and 13 deletions

View file

@ -59,5 +59,9 @@ class Settings(six.with_metaclass(SettingsBase)):
"""
@classmethod
def setup(cls):
def pre_setup(cls):
pass
@classmethod
def post_setup(cls):
pass

View file

@ -160,6 +160,7 @@ class SettingsLoader(object):
else:
mod = imp.load_module(fullname, *self.location)
cls_path = '%s.%s' % (mod.__name__, self.name)
try:
cls = getattr(mod, self.name)
except AttributeError as err: # pragma: no cover
@ -167,9 +168,10 @@ class SettingsLoader(object):
"While trying to find the '%s' settings in module '%s'" %
(self.name, mod.__package__))
try:
cls.setup()
cls.pre_setup()
except Exception as err:
reraise(err, "While calling '%s.setup()'" % cls_path)
reraise(err, "While calling '%s.pre_setup()'" % cls_path)
try:
obj = cls()
except Exception as err:
@ -193,4 +195,10 @@ class SettingsLoader(object):
setattr(mod, name, value)
setattr(mod, 'CONFIGURATION', '%s.%s' % (fullname, self.name))
try:
cls.post_setup()
except Exception as err:
reraise(err, "While calling '%s.post_setup()'" % cls_path)
return mod

View file

@ -54,5 +54,11 @@ class Test(Settings):
return 5
@classmethod
def setup(cls):
cls.SETUP_TEST_SETTING = 6
def pre_setup(cls):
cls.PRE_SETUP_TEST_SETTING = 6
@classmethod
def post_setup(cls):
cls.POST_SETUP_TEST_SETTING = 7
from django.conf import settings
settings.POST_SETUP_TEST_SETTING = 8

View file

@ -25,7 +25,8 @@ class MainTests(TestCase):
global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'configurations.tests.settings.base.test_callback',
))
self.assertEqual(main.SETUP_TEST_SETTING, 6)
self.assertEqual(main.PRE_SETUP_TEST_SETTING, 6)
self.assertRaises(AttributeError, lambda: main.POST_SETUP_TEST_SETTING)
def test_global_arrival(self):
from django.conf import settings
@ -35,7 +36,8 @@ 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)
self.assertEqual(settings.PRE_SETUP_TEST_SETTING, 6)
self.assertEqual(settings.POST_SETUP_TEST_SETTING, 8)
@patch.dict(os.environ, clear=True, DJANGO_CONFIGURATION='Test')
def test_empty_module_var(self):

View file

@ -160,9 +160,10 @@ 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::
If there is something required to be set up before or after the settings
loading happens, please override the ``pre_setup`` or ``post_setup``
class methods like so (don't forget to apply the Python ``@classmethod``
decorator::
from configurations import Settings
@ -170,11 +171,22 @@ to apply the Python ``@classmethod`` decorator::
# ...
@classmethod
def setup(cls):
def pre_setup(cls):
if something.completely.different():
cls.DEBUG = True
Or do something unrelated to your settings, like connecting to a database::
@classmethod
def post_setup(cls):
print("done setting up! \o/")
As you can see above the ``pre_setup`` method can also be used to
programmatically change a class attribute of the settings class and it
will be taken into account when doing the rest of the settings setup.
Of course that won't work for ``post_setup`` since that's when the
settings setup is already done.
In fact you can easily do something unrelated to settings, like
connecting to a database::
from configurations import Settings
@ -182,10 +194,22 @@ Or do something unrelated to your settings, like connecting to a database::
# ...
@classmethod
def setup(cls):
def post_setup(cls):
import mango
mango.connect('enterprise')
.. warning::
You could do the same by overriding the ``__init__`` method of your
settings class but this may cause hard to debug errors because
at the time the ``__init__`` method is called (during Django startup)
the Django setting system isn't fully loaded yet.
So anything you do in ``__init__`` that may require
``django.conf.settings`` or Django models there is a good chance it
won't work. Use the ``post_setup`` method for that instead.
Alternatives
------------