1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
"""Dynaconf django extension
In the `django_project/settings.py` put at the very botton of the file:
# HERE STARTS DYNACONF EXTENSION LOAD (Keep at the very bottom of settings.py)
# Read more at https://dynaconf.readthedocs.io/en/latest/guides/django.html
import dynaconf # noqa
settings = dynaconf.DjangoDynaconf(__name__) # noqa
# HERE ENDS DYNACONF EXTENSION LOAD (No more code below this line)
Now in the root of your Django project
(the same folder where manage.py is located)
Put your config files `settings.{py|yaml|toml|ini|json}`
and or `.secrets.{py|yaml|toml|ini|json}`
On your projects root folder now you can start as::
DJANGO_DEBUG='false' \
DJANGO_ALLOWED_HOSTS='["localhost"]' \
python manage.py runserver
"""
import inspect
import os
import sys
import dynaconf
try: # pragma: no cover
from django import conf
from django.conf import settings as django_settings
django_installed = True
except ImportError: # pragma: no cover
django_installed = False
def load(django_settings_module_name=None, **kwargs): # pragma: no cover
if not django_installed:
raise RuntimeError(
"To use this extension django must be installed "
"install it with: pip install django"
)
try:
django_settings_module = sys.modules[django_settings_module_name]
except KeyError:
django_settings_module = sys.modules[
os.environ["DJANGO_SETTINGS_MODULE"]
]
settings_file = os.path.abspath(django_settings_module.__file__)
_root_path = os.path.dirname(settings_file)
# 1) Create the lazy settings object reusing settings_module consts
options = {
k: v for k, v in django_settings_module.__dict__.items() if k.isupper()
}
options.update(kwargs)
options.setdefault(
"SKIP_FILES_FOR_DYNACONF", [settings_file, "dynaconf_merge"]
)
options.setdefault("ROOT_PATH_FOR_DYNACONF", _root_path)
options.setdefault("ENVVAR_PREFIX_FOR_DYNACONF", "DJANGO")
options.setdefault("ENV_SWITCHER_FOR_DYNACONF", "DJANGO_ENV")
options.setdefault("ENVIRONMENTS_FOR_DYNACONF", True)
options.setdefault("load_dotenv", True)
options.setdefault(
"default_settings_paths", dynaconf.DEFAULT_SETTINGS_FILES
)
class UserSettingsHolder(dynaconf.LazySettings):
_django_override = True
lazy_settings = dynaconf.LazySettings(**options)
dynaconf.settings = lazy_settings # rebind the settings
# 2) Set all settings back to django_settings_module for 'django check'
lazy_settings.populate_obj(django_settings_module)
# 3) Bind `settings` and `DYNACONF`
setattr(django_settings_module, "settings", lazy_settings)
setattr(django_settings_module, "DYNACONF", lazy_settings)
# 4) keep django original settings
dj = {}
for key in dir(django_settings):
if (
key.isupper()
and (key != "SETTINGS_MODULE")
and key not in lazy_settings.store
):
dj[key] = getattr(django_settings, key, None)
dj["ORIGINAL_SETTINGS_MODULE"] = django_settings.SETTINGS_MODULE
lazy_settings.update(dj)
# 5) Patch django.conf.settings
class Wrapper:
# lazy_settings = conf.settings.lazy_settings
def __getattribute__(self, name):
if name == "settings":
return lazy_settings
if name == "UserSettingsHolder":
return UserSettingsHolder
return getattr(conf, name)
# This implementation is recommended by Guido Van Rossum
# https://mail.python.org/pipermail/python-ideas/2012-May/014969.html
sys.modules["django.conf"] = Wrapper()
# 6) Enable standalone scripts to use Dynaconf
# This is for when `django.conf.settings` is imported directly
# on external `scripts` (out of Django's lifetime)
for stack_item in reversed(inspect.stack()):
if isinstance(
stack_item.frame.f_globals.get("settings"), conf.LazySettings
):
stack_item.frame.f_globals["settings"] = lazy_settings
return lazy_settings
# syntax sugar
DjangoDynaconf = load # noqa
|