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

2024-09-27 01:23:57 发布

您现在位置:Python中文网/ 问答频道 /正文

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

APPLES = 1

我可以在项目中的应用程序中使用settings.APPLES来访问它。

但是如果我的settings.py没有定义该值,那么访问settings.APPLES显然就行不通。如果settings.py中没有显式设置,是否有方法定义使用的APPLES的默认值?

我想在需要设置的模块/包中定义默认值。


Tags: 模块项目django方法文档py应用程序settings
3条回答

不如:

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

在我的应用程序中,我有一个单独的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将首先检查该属性,如果找到该属性,则返回该值,或者使用在应用程序设置文件中定义的默认值。

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

为单个应用程序配置默认值

在代码中使用from MYAPP import settings,而不是from django.conf import settings

编辑YOURAPP/__init__.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()

为整个项目配置默认值

在代码中使用from MYPROJECT import settings,而不是from django.conf import settings

编辑MYPROJECT/MYPROJECT/__init__.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中声明同一变量,则无法确定哪个应用程序将返回您要求的默认值。

相关问题 更多 >

    热门问题