django settings per application - best practice?

后端 未结 4 494
忘了有多久
忘了有多久 2021-02-01 12:58

this is somewhat related to this question
Why is django's settings object a LazyObject?

In my django project i have several applications. Each application can ha

相关标签:
4条回答
  • 2021-02-01 13:39

    My site is just starting and I want a the simplest but flexible configuration solution. That's what I came across with.

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

    In my application's models.py:

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

    This config parser is described here. It's convenient enough but definitely not the only option.

    0 讨论(0)
  • 2021-02-01 13:54

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

    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
    
    0 讨论(0)
  • 2021-02-01 13:56

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

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

    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
    

    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.py
    
    INSTALLED_APPS = [
        'app1.apps.App1Config',
        'app2.apps.App2Config',
        # ...
    ]
    

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

    from django.apps import apps
    apps.get_app_config('app1').OPTION_A
    
    0 讨论(0)
  • 2021-02-01 14:02

    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 settings
    from appconf import AppConf
    
    class MyAppConf(AppConf):
        SETTING_1 = "one"
        SETTING_2 = (
            "two",
        )
    

    And in your code:

    from myapp.conf import settings
    
    def 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"
    
    0 讨论(0)
提交回复
热议问题