Created
January 15, 2012 15:26
-
-
Save Jc2k/1616168 to your computer and use it in GitHub Desktop.
Lazier Django Settings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class RecurseLock(object): | |
| """ | |
| Maintain a stack of settings referenced by LazierSetting so we can trap recursion. | |
| We use a context manager to surround variable access, and ensure that the stack is cleared. | |
| Error message contains a stack trace:: | |
| Setting FOO was used recursively | |
| FOO -> BAR -> BAZ -> FOO | |
| """ | |
| locks = [] | |
| def __init__(self, name): | |
| self.name = name | |
| def __enter__(self): | |
| if self.name in self.locks: | |
| raise EnvironmentError('Setting "%s" was used recursively\n%s' % (self.name, " -> ".join(self.locks + [self.name]))) | |
| self.locks.append(self.name) | |
| return self | |
| def __exit__(self, *exc): | |
| assert self.locks[-1] == self.name | |
| self.locks[-1:] = [] | |
| class Dictify(object): | |
| """ In order to use ``%s`` substitutions in strings we needing a settings module to look like a Dict """ | |
| def __init__(self, obj): | |
| self.obj = obj | |
| def __getattr__(self, key): | |
| with RecurseLock(key): | |
| return getattr(self.obj, key) | |
| def __getitem__(self, key): | |
| with RecurseLock(key): | |
| return getattr(self.obj, key) | |
| class LazierSetting(object): | |
| """ | |
| We don't want to perform %s substitutions on all settings, so use a special | |
| proxy wrapper to mark strings. | |
| You can also pass a callable and it will be called with the settings object | |
| We alias LazierSetting as ``_`` for convenience. | |
| """ | |
| def __init__(self, value): | |
| self.value = value | |
| def render(self, settings): | |
| if callable(self.value): | |
| return self.value(settings) | |
| return self.value % settings | |
| _ = LazierSetting | |
| def install(): | |
| """ Patch the Django settings proxy object so that any subclasses of LazierSetting are | |
| rendered before they are returned to the caller """ | |
| from django import conf | |
| old_get_attr = conf.LazySettings.__getattr__ | |
| def custom_get_attr(self, key): | |
| val = old_get_attr(self, key) | |
| if isinstance(val, LazierSetting): | |
| return val.render(Dictify(self)) | |
| return val | |
| conf.LazySettings.__getattr__ = custom_get_attr |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from .settings import * | |
| DOMAIN = "wibble.com" | |
| """ | |
| Your change to ``DOMAIN`` will be reflected in ``SUPPORT_EMAIL``:: | |
| >>> from django.conf import settings | |
| >>> settings.SUPPORT_EMAIL | |
| ... [email protected] | |
| """ | |
| FOO = _("%(BAR)s") | |
| BAR = _("%(FOO)s") | |
| """ | |
| When you try to access either of these you will cause an EnvironmentError:: | |
| >>> from djano.conf import settings | |
| >>> settings.BAR | |
| ... EnvironmentError: Setting "BAR" was used recursively | |
| ... BAR -> FOO -> BAR | |
| """ | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from .lazy import _ | |
| DOMAIN = "localhost" | |
| SUPPORT_EMAIL = _("support@%(DOMAIN)s") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment