1
"""Dynaconf django extension
2

3
In the `django_project/settings.py` put at the very botton of the file:
4

5
# HERE STARTS DYNACONF EXTENSION LOAD (Keep at the very bottom of settings.py)
6
# Read more at https://dynaconf.readthedocs.io/en/latest/guides/django.html
7
import dynaconf  # noqa
8
settings = dynaconf.DjangoDynaconf(__name__)  # noqa
9
# HERE ENDS DYNACONF EXTENSION LOAD (No more code below this line)
10

11
Now in the root of your Django project
12
(the same folder where manage.py is located)
13

14
Put your config files `settings.{py|yaml|toml|ini|json}`
15
and or `.secrets.{py|yaml|toml|ini|json}`
16

17
On your projects root folder now you can start as::
18

19
    DJANGO_DEBUG='false' \
20
    DJANGO_ALLOWED_HOSTS='["localhost"]' \
21
    python manage.py runserver
22
"""
23 2
import inspect
24 2
import os
25 2
import sys
26

27 2
import dynaconf
28

29
try:  # pragma: no cover
30
    from django import conf
31
    from django.conf import settings as django_settings
32

33
    django_installed = True
34
except ImportError:  # pragma: no cover
35
    django_installed = False
36

37

38
def load(django_settings_module_name=None, **kwargs):  # pragma: no cover
39
    if not django_installed:
40
        raise RuntimeError(
41
            "To use this extension django must be installed "
42
            "install it with: pip install django"
43
        )
44

45
    try:
46
        django_settings_module = sys.modules[django_settings_module_name]
47
    except KeyError:
48
        django_settings_module = sys.modules[
49
            os.environ["DJANGO_SETTINGS_MODULE"]
50
        ]
51

52
    settings_file = os.path.abspath(django_settings_module.__file__)
53
    _root_path = os.path.dirname(settings_file)
54

55
    # 1) Create the lazy settings object reusing settings_module consts
56
    options = {
57
        k: v for k, v in django_settings_module.__dict__.items() if k.isupper()
58
    }
59
    options.update(kwargs)
60
    options.setdefault(
61
        "SKIP_FILES_FOR_DYNACONF", [settings_file, "dynaconf_merge"]
62
    )
63
    options.setdefault("ROOT_PATH_FOR_DYNACONF", _root_path)
64
    options.setdefault("ENVVAR_PREFIX_FOR_DYNACONF", "DJANGO")
65
    options.setdefault("ENV_SWITCHER_FOR_DYNACONF", "DJANGO_ENV")
66
    options.setdefault("ENVIRONMENTS_FOR_DYNACONF", True)
67
    options.setdefault("load_dotenv", True)
68
    options.setdefault(
69
        "default_settings_paths", dynaconf.DEFAULT_SETTINGS_FILES
70
    )
71

72
    lazy_settings = dynaconf.LazySettings(**options)
73
    dynaconf.settings = lazy_settings  # rebind the settings
74

75
    # 2) Set all settings back to django_settings_module for 'django check'
76
    lazy_settings.populate_obj(django_settings_module)
77

78
    # 3) Bind `settings` and `DYNACONF`
79
    setattr(django_settings_module, "settings", lazy_settings)
80
    setattr(django_settings_module, "DYNACONF", lazy_settings)
81

82
    # 4) keep django original settings
83
    dj = {}
84
    for key in dir(django_settings):
85
        if (
86
            key.isupper()
87
            and (key != "SETTINGS_MODULE")
88
            and key not in lazy_settings.store
89
        ):
90
            dj[key] = getattr(django_settings, key, None)
91
        dj["ORIGINAL_SETTINGS_MODULE"] = django_settings.SETTINGS_MODULE
92

93
    lazy_settings.update(dj)
94

95
    # 5) Patch django.conf.settings
96
    class Wrapper(object):
97

98
        # lazy_settings = conf.settings.lazy_settings
99

100
        def __getattribute__(self, name):
101
            if name == "settings":
102
                return lazy_settings
103
            else:
104
                return getattr(conf, name)
105

106
    # This implementation is recommended by Guido Van Rossum
107
    # https://mail.python.org/pipermail/python-ideas/2012-May/014969.html
108
    sys.modules["django.conf"] = Wrapper()
109

110
    # 6) Enable standalone scripts to use Dynaconf
111
    # This is for when `django.conf.settings` is imported directly
112
    # on external `scripts` (out of Django's lifetime)
113
    for stack_item in reversed(inspect.stack()):
114
        if isinstance(
115
            stack_item.frame.f_globals.get("settings"), conf.LazySettings
116
        ):
117
            stack_item.frame.f_globals["settings"] = lazy_settings
118

119
    return lazy_settings
120

121

122
# syntax sugar
123 2
DjangoDynaconf = load  # noqa

Read our documentation on viewing source code .

Loading