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

时间:2021-10-16 07:39:13

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

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

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?

但是如果我的设置。py没有定义这个值,而是访问设置。苹果显然是行不通的。如果settings.py中没有显式设置,是否有办法为苹果定义一个默认值?

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

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

5 个解决方案

#1


26  

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.

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

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.

这允许在项目设置中覆盖覆盖。py, getattr将首先检查并返回值,如果该属性被发现或使用应用程序设置文件中定义的默认值。

#2


12  

How about just:

只是如何:

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

#3


6  

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

这里有两种解决方案。你可以设置设置。应用程序中的py文件,并使用默认值填充它们。

Configure default value for a single application

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

使用从MYAPP导入设置,而不是从django。在代码中导入设置。

Edit YOURAPP/__init__.py:

编辑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.

从MYPROJECT导入设置中使用,而不是从django中使用。在代码中导入设置。

Edit MYPROJECT/MYPROJECT/__init__.py

编辑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.

这个解决方案看起来更容易安装,但是它不能保证返回的是好的默认值。如果多个应用程序在其设置中声明相同的变量。py,您不能确定哪个将返回您所请求的默认值。

#4


2  

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

从Mike的回答开始,我现在将默认设置处理封装到一个易于使用接口的类中。

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.

这将从django.conf打印值。设置,或者默认设置,如果没有设置。这个settings对象也可以用来访问所有的标准设置值。

#5


0  

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.

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

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

这个应用程序可以在:https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display

#1


26  

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.

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

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.

这允许在项目设置中覆盖覆盖。py, getattr将首先检查并返回值,如果该属性被发现或使用应用程序设置文件中定义的默认值。

#2


12  

How about just:

只是如何:

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

#3


6  

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

这里有两种解决方案。你可以设置设置。应用程序中的py文件,并使用默认值填充它们。

Configure default value for a single application

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

使用从MYAPP导入设置,而不是从django。在代码中导入设置。

Edit YOURAPP/__init__.py:

编辑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.

从MYPROJECT导入设置中使用,而不是从django中使用。在代码中导入设置。

Edit MYPROJECT/MYPROJECT/__init__.py

编辑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.

这个解决方案看起来更容易安装,但是它不能保证返回的是好的默认值。如果多个应用程序在其设置中声明相同的变量。py,您不能确定哪个将返回您所请求的默认值。

#4


2  

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

从Mike的回答开始,我现在将默认设置处理封装到一个易于使用接口的类中。

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.

这将从django.conf打印值。设置,或者默认设置,如果没有设置。这个settings对象也可以用来访问所有的标准设置值。

#5


0  

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.

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

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

这个应用程序可以在:https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display