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

发布于 2024-10-31 10:15:57 字数 505 浏览 1 评论 0原文

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

APPLES = 1

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

但是,如果我的 settings.py 没有定义该值,则访问 settings.APPLES 显然将无法工作。如果 settings.py 中没有显式设置,是否有某种方法可以为 APPLES 定义默认值?

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

The Django documentation mentions that you can add your own settings to django.conf.settings. So if my project's settings.py defines

APPLES = 1

I can access that with settings.APPLES in my apps in that project.

But if my settings.py doesn't define that value, accessing settings.APPLES obviously won't work. Is there some way to define a default value for APPLES that is used if there is no explicit setting in settings.py?

I'd like best to define the default value in the module/package that requires the setting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

刘备忘录 2024-11-07 10:15:57

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

from django.conf import settings

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


APPLES = get('APPLES', 1)

然后,在我需要访问 APPLES 的地方,我有:

from myapp import settings as myapp_settings

myapp_settings.APPLES

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

In my apps, I have a seperate settings.py file. In that file I have a get() function that does a look up in the projects settings.py file and if not found returns the default value.

from django.conf import settings

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


APPLES = get('APPLES', 1)

Then where I need to access APPLES I have:

from myapp import settings as myapp_settings

myapp_settings.APPLES

This allows an override in the projects settings.py, getattr will check there first and return the value if the attribute is found or use the default defined in your apps settings file.

哆啦不做梦 2024-11-07 10:15:57

怎么样:

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

How about just:

getattr(app_settings, 'SOME_SETTING', 'default value')
泪痕残 2024-11-07 10:15:57

这里有两个解决方案。对于这两种情况,您都可以在应用程序中设置 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 中声明相同的变量,您无法确定哪一个应用程序将返回您要求的默认值。

Here are two solutions. For both you can set settings.py files in your applications and fill them with default values.

Configure default value for a single application

Use from MYAPP import settings instead of from django.conf import settings in your code.

Edit 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()

Configure default values for a whole project

Use from MYPROJECT import settings instead of from django.conf import settings in your code.

Edit 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()

This solution may seem more easier to install, but it does not guarantee that the good default value will be returned. If several applications declare the same variable in their settings.py, you can not be sure which one will return the default value you asked.

巴黎夜雨 2024-11-07 10:15:57

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

帮助程序模块:

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 中的值,如果未在那里设置,则打印默认值。此 settings 对象还可用于访问所有标准设置值。

Starting from Mike's answer, I now wrapped the default setting handling into a class with easy to use interface.

Helper module:

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

Usage:

from localconf import SettingsView

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

print settings.APPLES

This prints the value from django.conf.settings, or the default if it isn't set there. This settings object can also be used to access all the standard setting values.

薔薇婲 2024-11-07 10:15:57

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

我将其扩展为还允许对默认值进行某些类型检查或预先处理(例如,可以在加载时将点分类路径转换为类本身)

该应用程序可以在以下位置找到: https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display

I recently had the same problem and created a Django app that is designed to be used for exactly such a case. It allows you to define default values for certain settings. It then first checks whether the setting is set in the global settings file. If not, it will return the default value.

I've extended it to also allow for some type checking or pre handling of the default value (e.g. a dotted class path can be converted to the class itself on load)

The app can be found at: https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文