django settings per application - best practice? django settings per application - best practice? python python

django settings per application - best practice?


The simplest solution is to use the getattr(settings, 'MY_SETTING', 'my_default') trick that you mention youself. It can become a bit tedious to have to do this in multiple places, though.

Extra recommendation: use a per-app prefix like MYAPP_MY_SETTING.

There is a django app, however, that gets rid of the getattr and that handles the prefix for you. See http://django-appconf.readthedocs.org/en/latest/

Normally you create a conf.py per app with contents like this:

from django.conf import settingsfrom appconf import AppConfclass MyAppConf(AppConf):    SETTING_1 = "one"    SETTING_2 = (        "two",    )

And in your code:

from myapp.conf import settingsdef my_view(request):    return settings.MYAPP_SETTINGS_1  # Note the handy prefix

Should you need to customize the setting in your site, a regular entry in your site's settings.py is all you need to do:

MYAPP_SETTINGS_1 = "four, four I say"


Since Django 1.7 there is a django-based structure for app-oriented configurations!You could find descriptive solution here

In this new structure, conventionally you could have an apps.py file in your applications' folder which are embeded in project, something like this:

proj/    proj/         settings.py    app1/        apps.py        views.py    app2/        apps.py        views.py

app1/apps.py file could include something like this:

from django.apps import AppConfigclass App1Config(AppConfig):    # typical systemic configurations    name = 'app1'    verbose_name = 'First App'    # your desired configurations    OPTION_A = 'default_value'    APP_NAMESPACE = 'APP'    APP_OPTION_B = 4

you could have app2/apps.py something different like this:

from django.apps import AppConfigclass App2Config(AppConfig):    # typical systemic configurations    name = 'app2'    verbose_name = 'Second App'    # your desired configurations    OTHER_CONFIGURATION = 'default_value'    OPTION_C = 5

and so etc for other apps.pys in you Django Application folder.

It's important that you should import applications you included apps.py in, as follows:

# proj/settings.pyINSTALLED_APPS = [    'app1.apps.App1Config',    'app2.apps.App2Config',    # ...]

‌Now, You could access desired app-based configuration someway like this:

from django.apps import appsapps.get_app_config('app1').OPTION_A


Not sure about best practices but I don't have any problems with following style:

proj/settings.py

OPTION_A = 'value'# or with namespaceAPP_NAMESPACE = 'APP'APP_OPTION_B = 4

app/settings.py

from django.conf import settingsfrom django.utils.functional import SimpleLazyObjectOPTION_A = getattr(settings, 'OPTION_A', 'default_value')# or with namespaceNAMESPACE = getattr(settings, APP_NAMESPACE, 'APP')OPTION_B = getattr(settings, '_'.join([NAMESPACE, 'OPTION_B']), 'default_value')OPTION_C = getattr(settings, '_'.join([NAMESPACE, 'OPTION_C']), None)if OPTION_C is None:    raise ImproperlyConfigured('...')# lazy option with long initializationOPTION_D = SimpleLazyObject(lambda: open('file.txt').read())

app/views.py

from .settings import OPTION_A, OPTION_B# orfrom . import settings as app_settingsapp_settings.OPTION_Capp_settings.OPTION_D  # initialized on access