web-dev-qa-db-fra.com

django paramètres par application - meilleure pratique?

c'est quelque peu lié à cette question
Pourquoi l'objet paramètres de Django est-il un LazyObject?

Dans mon projet Django j'ai plusieurs applications. Chaque application peut avoir son propre fichier de paramètres non trivial.

proj/
    proj/
         settings.py
    app/
         settings.py
         views.py

Quelle est la meilleure pratique générale ici?
devrait faire app/settings.py do

from Django.conf import settings
APP_SETTING= lambda: settings.getattr('APP_SETTING', 'custom_value')
PROJ_SETTING= lambda: settings.PROJ_SETTING

puis dans app/views.py do

import .settings 
X = settings.APP_SETTING
Y = settings.PROJ_SETTING

ou dois-je modifier l'objet Django lazy settings dans app/settings.py selon le style de codage Django?

from Django.conf import settings
# not even sure how I would check for a default value that was specified in proj/settings.py
settings.configure(APP_SETTING='custom_value')

puis chaque app/views.py consomme juste proj/settings.py via les paramètres Django.conf?

from Django.conf import settings
X = settings.APP_SETTING
Y = settings.PROJ_SETTING

Il y a évidemment plusieurs autres permutations mais je pense que mon intention est claire.
Merci d'avance.

38
w--

La solution la plus simple consiste à utiliser l'astuce getattr(settings, 'MY_SETTING', 'my_default') que vous mentionnez vous-même. Cependant, cela peut devenir un peu fastidieux de devoir le faire à plusieurs endroits.

Recommandation supplémentaire: utilisez un préfixe par application tel que MYAPP_MY_SETTING.

Il existe cependant une application Django qui se débarrasse de getattr et qui gère le préfixe pour vous. Voir http: //Django-appconf.readthedocs .org/en/latest /

Normalement, vous créez un conf.py par application avec un contenu comme celui-ci:

from Django.conf import settings
from appconf import AppConf

class MyAppConf(AppConf):
    SETTING_1 = "one"
    SETTING_2 = (
        "two",
    )

Et dans votre code:

from myapp.conf import settings

def my_view(request):
    return settings.MYAPP_SETTINGS_1  # Note the handy prefix

Si vous devez personnaliser le paramètre de votre site, une entrée régulière dans le settings.py est tout ce que vous devez faire:

MYAPP_SETTINGS_1 = "four, four I say"
9
Reinout van Rees

Depuis Django 1.7 il existe une structure basée sur Django pour les configurations orientées application! Vous pouvez trouver une solution descriptive ici

Dans cette nouvelle structure, vous pouvez classiquement avoir un apps.py fichier dans le dossier de vos applications qui sont incorporées dans le projet, quelque chose comme ceci:

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

app1/apps.py le fichier pourrait inclure quelque chose comme ceci:

from Django.apps import AppConfig


class 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

tu aurais pu app2/apps.py quelque chose de différent comme ceci:

from Django.apps import AppConfig


class App2Config(AppConfig):
    # typical systemic configurations
    name = 'app2'
    verbose_name = 'Second App'

    # your desired configurations
    OTHER_CONFIGURATION = 'default_value'
    OPTION_C = 5

et ainsi de suite pour les autres apps.pys en vous Django Dossier d'application.

Il est important d'importer les applications que vous avez incluses apps.py in, comme suit:

# proj/settings.py

INSTALLED_APPS = [
    'app1.apps.App1Config',
    'app2.apps.App2Config',
    # ...
]

OwMaintenant, vous pouvez accéder à la configuration basée sur l'application souhaitée de la manière suivante:

from Django.apps import apps
apps.get_app_config('app1').OPTION_A
5
AbdolHosein

Je ne suis pas sûr des meilleures pratiques mais je n'ai aucun problème avec le style suivant:

proj/settings.py

OPTION_A = 'value'

# or with namespace
APP_NAMESPACE = 'APP'
APP_OPTION_B = 4

app/settings.py

from Django.conf import settings
from Django.utils.functional import SimpleLazyObject

OPTION_A = getattr(settings, 'OPTION_A', 'default_value')

# or with namespace
NAMESPACE = 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 initialization
OPTION_D = SimpleLazyObject(lambda: open('file.txt').read())

app/views.py

from .settings import OPTION_A, OPTION_B
# or
from . import settings as app_settings
app_settings.OPTION_C
app_settings.OPTION_D  # initialized on access
2
Viktor Danyliuk