如何为自定义Django设置定义默认值

如何为自定义Django设置定义默认值,django,default-value,django-settings,Django,Default Value,Django Settings,Django文档,您可以将自己的设置添加到Django.conf.settings。因此,如果我的项目的settings.py定义 APPLES = 1 我可以通过该项目中我的应用程序中的settings.APPLES来访问它 但是如果我的settings.py没有定义该值,那么访问settings.APPLES显然是不起作用的。如果在settings.py中没有明确的设置,是否有办法为APPLES定义默认值 我最好在需要设置的模块/软件包中定义默认值。在我的应用程序中,我有一个单独的sett

Django文档,您可以将自己的设置添加到
Django.conf.settings
。因此,如果我的项目的
settings.py
定义

APPLES = 1
我可以通过该项目中我的应用程序中的
settings.APPLES
来访问它

但是如果我的
settings.py
没有定义该值,那么访问
settings.APPLES
显然是不起作用的。如果在
settings.py
中没有明确的设置,是否有办法为
APPLES
定义默认值


我最好在需要设置的模块/软件包中定义默认值。

在我的应用程序中,我有一个单独的settings.py文件。在该文件中,我有一个get()函数,它在projects settings.py文件中进行查找,如果找不到,则返回默认值

from django.conf import settings

def get(key, default):
    return getattr(settings, key, default)


APPLES = get('APPLES', 1)
然后,我需要访问苹果的地方有:

from myapp import settings as myapp_settings

myapp_settings.APPLES

这允许在projects settings.py中进行覆盖,getattr将首先检查该属性,如果找到该属性或使用应用程序设置文件中定义的默认值,则返回该值。

从Mike的答案开始,我现在将默认设置处理包装到一个具有易于使用界面的类中

辅助模块:

from django.conf import settings

class SettingsView(object):
   class Defaults(object):
      pass

   def __init__(self):
      self.defaults = SettingsView.Defaults()

   def __getattr__(self, name):
      return getattr(settings, name, getattr(self.defaults, name))
用法:

from localconf import SettingsView

settings = SettingsView()
settings.defaults.APPLES = 1

print settings.APPLES
这将打印
django.conf.settings
中的值,如果没有设置,则打印默认值。此
设置
对象也可用于访问所有标准设置值。

如何:

getattr(app_settings, 'SOME_SETTING', 'default value')

这里有两个解决方案。对于这两种设置,您可以在应用程序中设置
settings.py
文件,并用默认值填充它们

为单个应用程序配置默认值 在代码中使用MYAPP导入设置中的
,而不是django.conf导入设置中的

编辑你的应用程序/\uuuuu init\uuuuuuy.py

from django.conf import settings as user_settings
from . import settings as default_settings

class AppSettings:
    def __getattr__(self, name):
        # If the setting you want is filled by the user, let's use it.
        if hasattr(user_settings, name):
            return getattr(user_settings, name)

        # If the setting you want has a default value, let's use it.
        if hasattr(default_settings, name):
            return getattr(default_settings, name)

        raise AttributeError("'Settings' object has no attribute '%s'" % name)

settings = AppSettings()
为整个项目配置默认值 在代码中使用MYPROJECT导入设置中的
,而不是django.conf导入设置中的

编辑
MYPROJECT/MYPROJECT/\uuuuuu init\uuuuuuu.py

import os, sys, importlib
from . import settings as user_settings

def get_local_apps():
    """Returns the locally installed apps names"""
    apps = []
    for app in user_settings.INSTALLED_APPS:
        path = os.path.join(user_settings.BASE_DIR, app)
        if os.path.exists(path) and app != __name__:
            apps.append(sys.modules[app])
    return apps

class AppSettings:
    SETTINGS_MODULE = 'settings'

    def __getattr__(self, setting_name):

        # If the setting you want is filled by the user, let's use it.
        if hasattr(user_settings, setting_name):
            return getattr(user_settings, setting_name)

        # Let's check every local app loaded by django.
        for app in get_local_apps():
            module_source = os.path.join(app.__path__[0], "%s.py" % self.SETTINGS_MODULE)
            module_binary = os.path.join(app.__path__[0], "%s.pyc" % self.SETTINGS_MODULE)
            if os.path.exists(module_source) or os.path.exists(module_binary):
                module = importlib.import_module("%s.%s" % (app.__name__, self.SETTINGS_MODULE))

                # Let's take the first default value for this setting we can find in any app
                if hasattr(module, setting_name):
                    return getattr(module, setting_name)

        raise AttributeError("'Settings' object has no attribute '%s'" % setting_name)

settings = AppSettings()

此解决方案似乎更易于安装,但它不能保证返回良好的默认值。如果多个应用程序在其settings.py中声明了相同的变量,您无法确定哪个应用程序将返回您要求的默认值。

我最近遇到了同样的问题,并创建了一个Django应用程序,该应用程序专为这种情况而设计。它允许您为某些设置定义默认值。然后,它首先检查是否在全局设置文件中设置了该设置。如果不是,它将返回默认值

from django.conf import settings

def get(key, default):
    return getattr(settings, key, default)


APPLES = get('APPLES', 1)
我对它进行了扩展,允许对默认值进行一些类型检查或预处理(例如,点式类路径可以在加载时转换为类本身)


该应用程序可在以下网址找到:

我认为应用程序特定的设置应该明确命名,并与主设置不同,以便于阅读。这比这里的其他建议简单得多,但如果你打算多次使用设置/变量,你就打破了枯燥的概念,在这种情况下,其他解决方案可能会起作用。值得思考的是:)它是如何变干的?如果你想在你的应用程序中多次使用某些设置,那么你必须将这个
getattr(app\u settings,'SOME\u SETTING',default\u value)
放在你使用它的任何地方,就放在你想要默认设置的任何地方。这不是很脆弱吗?不依赖于在
app\u settings.py
之前导入的项目
settings.py
?@Flimm yes。如果您尝试直接导入
myapp\u设置
,它将在第一次导入时初始化Django的
getattr
,并给出一个配置错误(因为在我们对其进行评估时,将返回部分评估的
myapp\u设置
模块,而不是进入一个无休止的导入循环)。我还没有找到一个干净的解决办法。