django-instellingen per applicatie – best practice?

dit hangt enigszins samen met deze vraag
Waarom is het instellingenobject van django een LazyObject?

In mijn django-project heb ik verschillende toepassingen. Elke applicatie kan zijn eigen niet-triviale instellingenbestand hebben.

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

Wat is hier de algemene best practice?
moet app/settings.py doen

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

en dan in app/views.py doen

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

of moet ik het django lazy-instellingenobject in app/settings.py aanpassen volgens de django-coderingsstijl?

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')

en dan verbruikt elke app/views.py gewoon proj/settings.py via django.conf-instellingen?

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

Er zijn natuurlijk nogal wat andere permutaties, maar ik denk dat mijn bedoeling duidelijk is.
Bij voorbaat dank.


Antwoord 1, autoriteit 100%

De eenvoudigste oplossing is om de getattr(settings, 'MY_SETTING', 'my_default')truc te gebruiken die je zelf noemt. Het kan echter een beetje vervelend worden om dit op meerdere plaatsen te moeten doen.

Extra aanbeveling: gebruik een voorvoegsel per app, zoals MYAPP_MY_SETTING.

Er is echter een django-app die de getattrverwijdert en die het voorvoegsel voor u afhandelt. Zie http://django-appconf.readthedocs.org/en/latest/

Normaal gesproken maak je een conf.pyper app met inhoud als deze:

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

En in uw code:

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

Als u de instelling op uw site moet aanpassen, volstaat een regelmatige vermelding in settings.pyvan uw site:

MYAPP_SETTINGS_1 = "four, four I say"

Antwoord 2, autoriteit 47%

Sinds Django 1.7 is er een op django gebaseerde structuur voor app-georiënteerde configuraties!
U kunt hier

een beschrijvende oplossing vinden

In deze nieuwe structuur zou je normaal gesproken een apps.py-bestand in de map van je toepassingen kunnen hebben die in het project is ingesloten, ongeveer als volgt:

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

app1/apps.py-bestand kan zoiets als dit bevatten:

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

je zou app2/apps.pyiets anders kunnen hebben, zoals dit:

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

en zo enz. voor andere apps.pys in je Django Application-map.

Het is belangrijk dat u toepassingen waarin u apps.pyheeft opgenomen, als volgt importeert:

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

‌Nu zou je op de volgende manier toegang kunnen krijgen tot de gewenste app-gebaseerde configuratie:

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

Antwoord 3, autoriteit 32%

Ik weet niet zeker wat de beste werkwijzen zijn, maar ik heb geen problemen met de volgende stijl:

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

Antwoord 4

Mijn site is net begonnen en ik wil een de eenvoudigste maar flexibele configuratie-oplossing. Dat is wat ik tegenkwam.

# in the end of the site's settings.py
. . .
# Custom settings
MYAPP_CONFIG_FILE = "/home/user/config/myapp_config.ini"

In models.pyvan mijn toepassing:

from django.conf import settings
import configparser
config = configparser.ConfigParser()
config.read(settings.MYAPP_CONFIG_FILE, encoding='utf_8')

Deze configuratie-parser wordt hierbeschreven. Het is handig genoeg, maar zeker niet de enige optie.


Antwoord 5

u kunt django-zero-settingsgebruiken, hiermee kunt u uw standaardinstellingen definiëren en een keyvoor uw gebruikersinstellingen, dan zal het ook gebruikersoverschrijvingen afhandelen.

het importeert ook automatisch uw instellingen, kan verwijderde instellingen verwerken en kan ook vooraf instellingen controleren.

definieer bijvoorbeeld uw instellingen:

from zero_settings import ZeroSettings
app_settings = ZeroSettings(
    key="APP",
    defaults={
        "TOKEN": "token"
    },
)

dan kun je het gebruiken als:

from app.settings import app_settings
print(app_settings.TOKEN)

Other episodes