【问题标题】:django settings per application - best practice?每个应用程序的 django 设置 - 最佳实践?
【发布时间】:2014-04-18 15:46:06
【问题描述】:

这与这个问题有些相关
Why is django's settings object a LazyObject?

在我的 django 项目中,我有几个应用程序。每个应用程序都可以有自己的重要设置文件。

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

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

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

然后在 app/views.py 中做

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

还是应该按照 django 编码风格修改 app/settings.py 中的 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')

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

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

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

【问题讨论】:

标签: python django django-settings


【解决方案1】:

最简单的解决方案是使用您自己提到的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",
    )

在你的代码中:

from myapp.conf import settings

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

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

MYAPP_SETTINGS_1 = "four, four I say"

【讨论】:

  • "django-appconf" 确实很不错。
  • Django 为每个新应用程序创建 apps.py 文件。该文件包含一个继承自 AppConfig 的类。这可以用于相同的目的吗?
  • 不,那是不同的 appconfig。根据pypi.python.org/pypi/django-appconf 的说法,“换句话说,它们解决了与 django-appconf 相关但不同的用例,不能轻易用作替代品。名称相似纯属巧合。”
【解决方案2】:

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

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

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

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

你可以有 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

对于 Django 应用程序文件夹中的其他 apps.pys 等等。

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

# proj/settings.py

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

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

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

【讨论】:

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

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

项目/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

【讨论】:

    【解决方案4】:

    我的网站刚刚起步,我想要一个最简单但灵活的配置解决方案。这就是我遇到的。

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

    在我的应用程序的models.py

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

    这个配置解析器被描述为here。它足够方便,但绝对不是唯一的选择。

    【讨论】:

      【解决方案5】:

      你可以使用django-zero-settings,它可以让你定义你的默认值和一个key为你的用户设置,然后它也会处理用户覆盖。

      它还可以自动导入您的设置,能够处理已删除的设置,并且还可以预先检查设置。

      例如,定义您的设置:

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

      那么你可以像这样使用它:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-25
        • 2014-10-12
        • 2011-05-17
        • 2018-12-08
        • 2014-03-18
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        相关资源
        最近更新 更多