Как определить значение по умолчанию для пользовательской настройки Django
Документация Django упоминает, что вы можете добавить свои собственные настройки в django.conf.settings
. Поэтому, если мой проект settings.py
определяет
APPLES = 1
Я могу получить доступ к этому с помощью settings.APPLES
в моих приложениях в этом проекте.
Но если мой settings.py
не определяет это значение, доступ к settings.APPLES
, очевидно, не будет работать. Есть ли способ определить значение по умолчанию для APPLES
, которое используется, если в settings.py
нет явного значения?
Мне бы лучше всего определить значение по умолчанию в модуле/пакете, для которого требуется настройка.
Ответы
Ответ 1
В моих приложениях у меня есть отдельный файл settings.py. В этом файле у меня есть функция get(), которая просматривает файл настроек settings.py и, если не найден, возвращает значение по умолчанию.
from django.conf import settings
def get(key, default):
getattr(settings, key, default)
APPLES = get('APPLES', 1)
Тогда, когда мне нужно получить доступ к ЯДЯМ, я:
from myapp import settings as myapp_settings
myapp_settings.APPLES
Это позволяет переопределить параметры projects.py, getattr проверит их первым и вернет значение, если атрибут найден или использует значение по умолчанию, указанное в файле настроек ваших приложений.
Ответ 2
Как насчет просто:
getattr(app_settings, 'SOME_SETTING', 'default value')
Ответ 3
Вот два решения. Для обоих вы можете установить 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 use it.
if hasattr(user_settings, name):
return getattr(user_settings, name)
# If the setting you want has a default value, let 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 use it.
if hasattr(user_settings, setting_name):
return getattr(user_settings, setting_name)
# Let 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 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, вы не можете быть уверены, какой из них будет возвращать заданное по умолчанию значение.
Ответ 4
Начиная с ответа Майка, теперь я завернул обработку настроек по умолчанию в класс с простым в использовании интерфейсом.
Вспомогательный модуль:
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
также может использоваться для доступа ко всем стандартным значениям настройки.
Ответ 5
Вы можете проверить, задан ли параметр, а если нет, укажите значение по умолчанию. Например, вы можете определить вспомогательную функцию setting_default
следующим образом:
from django.conf import settings
def setting_default(name, default_value):
value = getattr(settings, name, default_value)
setattr(settings, name, value)
И затем используйте его в приложении, которое требует настройки (возможно, в models.py
), например:
setting_default('APPLES', 1)
Таким образом, любой, кто использует ваше приложение, не должен делать ничего особенного.
Ответ 6
Недавно у меня была такая же проблема, и я создал приложение Django, предназначенное для использования именно в таком случае. Он позволяет определять значения по умолчанию для определенных параметров. Затем он сначала проверяет, задан ли параметр в файле глобальных настроек. Если нет, он вернет значение по умолчанию.
Я расширил его, чтобы также разрешить некоторую проверку типа или предварительную обработку значения по умолчанию (например, путь точечного класса может быть преобразован в сам класс при загрузке)
Приложение можно найти по адресу: https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display