每个应用程序的django设置 - 最佳实践?

w--*_*w-- 35 python django django-settings

这有点与这个问题有关
为什么django的设置对象是一个LazyObject?

在我的django项目中,我有几个应用程序.每个应用程序都可以拥有自己的非平凡设置文件.

proj/
    proj/
         settings.py
    app/
         settings.py
         views.py
Run Code Online (Sandbox Code Playgroud)

这里的一般最佳做法是什么?
app/settings.py应该这样做

from django.conf import settings
APP_SETTING= lambda: settings.getattr('APP_SETTING', 'custom_value')
PROJ_SETTING= lambda: settings.PROJ_SETTING
Run Code Online (Sandbox Code Playgroud)

然后在app/views.py中

import .settings 
X = settings.APP_SETTING
Y = settings.PROJ_SETTING
Run Code Online (Sandbox Code Playgroud)

或者我应该根据django编码风格修改app/settings.py中的django lazy设置对象?

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')
Run Code Online (Sandbox Code Playgroud)

然后每个app/views.py只通过django.conf设置消耗proj/settings.py?

from django.conf import settings
X = settings.APP_SETTING
Y = settings.PROJ_SETTING
Run Code Online (Sandbox Code Playgroud)

显然有很多其他的排列,但我认为我的意图很明确.
提前致谢.

Abd*_*ein 9

从 Django 1.7 开始,有一个基于 django 的结构用于面向应用程序的配置!您可以在此处找到描述性解决方案

在这个新结构中,通常你可以apps.py在你的应用程序文件夹中有一个文件嵌入到项目中,如下所示:

proj/
    proj/
         settings.py
    app1/
        apps.py
        views.py
    app2/
        apps.py
        views.py
Run Code Online (Sandbox Code Playgroud)

app1/apps.py 文件可能包含如下内容:

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
Run Code Online (Sandbox Code Playgroud)

你可以有app2/apps.py这样的不同:

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
Run Code Online (Sandbox Code Playgroud)

等等等等,用于apps.py您 Django Application 文件夹中的其他s。

重要的是您应该导入您包含的应用程序apps.py,如下所示:

# proj/settings.py

INSTALLED_APPS = [
    'app1.apps.App1Config',
    'app2.apps.App2Config',
    # ...
]
Run Code Online (Sandbox Code Playgroud)

?现在,您可以像这样访问所需的基于应用程序的配置:

from django.apps import apps
apps.get_app_config('app1').OPTION_A
Run Code Online (Sandbox Code Playgroud)

  • 我不认为这个解决方案解决了OP问题——它不允许人们覆盖项目设置中的默认应用程序配置。使用此处的代码,您将始终获得应用程序的本地默认配置设置值。理想情况下,像 https://pypi.python.org/pypi/django-appconf 这样的东西会被集成到 django.apps.AppConfig 中,这样这个常见问题的简单、标准的解决方案就是现成的。 (7认同)

Rei*_*ees 8

最简单的解决方案是使用getattr(settings, 'MY_SETTING', 'my_default')你自己提到的技巧.但是,必须在多个地方执行此操作会变得有点乏味.

额外建议:使用每个应用程序前缀MYAPP_MY_SETTING.

但是,有一个django应用程序可以摆脱getattr并为您处理前缀.见http://django-appconf.readthedocs.org/en/latest/

通常,您conf.py使用以下内容创建每个应用程序:

from django.conf import settings
from appconf import AppConf

class MyAppConf(AppConf):
    SETTING_1 = "one"
    SETTING_2 = (
        "two",
    )
Run Code Online (Sandbox Code Playgroud)

在你的代码中:

from myapp.conf import settings

def my_view(request):
    return settings.MYAPP_SETTINGS_1  # Note the handy prefix
Run Code Online (Sandbox Code Playgroud)

如果您需要自定义站点中的设置,您需要在站点中定期输入settings.py:

MYAPP_SETTINGS_1 = "four, four I say"
Run Code Online (Sandbox Code Playgroud)


小智 6

不确定最佳实践,但我对以下风格没有任何问题:

项目/设置.py

OPTION_A = 'value'

# or with namespace
APP_NAMESPACE = 'APP'
APP_OPTION_B = 4
Run Code Online (Sandbox Code Playgroud)

应用程序/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())
Run Code Online (Sandbox Code Playgroud)

应用程序/视图.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
Run Code Online (Sandbox Code Playgroud)