Как определить значение по умолчанию для пользовательской настройки Django - PullRequest
29 голосов
/ 09 апреля 2011

В документации Django упоминается , что вы можете добавить свои собственные настройки в django.conf.settings. Так что, если мой проект settings.py определяет

APPLES = 1

Я могу получить к нему доступ с помощью settings.APPLES в моих приложениях в этом проекте.

Но если мой settings.py не определит это значение, доступ к settings.APPLES, очевидно, не будет работать. Есть ли способ определить значение по умолчанию для APPLES, которое используется, если в settings.py нет явных настроек?

Я бы лучше определил значение по умолчанию в модуле / пакете, который требует настройки.

Ответы [ 5 ]

28 голосов
/ 09 апреля 2011

В моих приложениях у меня есть отдельный файл 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 сначала проверит там и вернет значение, если атрибут найден, или использует значение по умолчанию, определенное в файле настроек вашего приложения.

13 голосов
/ 07 апреля 2015

Как насчет просто:

getattr(app_settings, 'SOME_SETTING', 'default value')
6 голосов
/ 26 августа 2015

Вот два решения. Для обоих вы можете установить 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, вы не можете быть уверены, какое из них возвратит заданное вами значение по умолчанию.

2 голосов
/ 09 апреля 2011

Начиная с ответа Майка, я теперь обернул обработку параметров по умолчанию в класс с простым в использовании интерфейсом.

Вспомогательный модуль:

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 также можно использовать для доступа ко всем стандартным значениям настроек.

0 голосов
/ 29 сентября 2015

Недавно у меня возникла та же проблема, и я создал приложение Django, предназначенное для использования именно в таком случае.Это позволяет вам определять значения по умолчанию для определенных настроек.Затем сначала проверяется, установлена ​​ли настройка в файле глобальных настроек.Если нет, он вернет значение по умолчанию.

Я расширил его, чтобы также позволить некоторую проверку типов или предварительную обработку значения по умолчанию (например, путь класса с точками можно преобразовать в сам класс при загрузке)

Приложение можно найти по адресу: https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...