Стандарт по умолчанию для Django для подключаемого приложения?

Что такое djangonautic способ обработки настроек по умолчанию в приложении, если он не определен в settings.py ?

В настоящее время я разместил файл default_settings в приложении, и я рассмотрел несколько вариантов. Я склоняюсь к первому варианту, но могут быть подводные камни, о которых я не знаю, используя globals()

В основном я видел, что приложения выполняют FOO = getattr(settings, 'FOO', False) в верхней части файла, который использует этот параметр, но я думаю, что есть проблемы чтения / повторения с этим подходом, если значения / имена длинны.


1: установка параметров в функции и повторение по локалям / установка глобальных переменных

 def setup_defaults(): FOO = 'bar' for key, value in locals().items(): globals()[key] = getattr(settings, key, value) setup_defaults() 

Плюсы:

  • Только нужно написать имя var один раз, чтобы вытащить значение по умолчанию с тем же именем из настроек django.

Минусы:

  • Не используется для использования глобальных переменных () и не знает каких-либо последствий

2: Напишите getattr(settings, 'MY_SETTING', default_settings.MY_SETTING) каждый вызов

Плюсы: – Очень ясно.

Минусы: – Повторяющиеся


3: Всегда FOO = getattr(settings, 'FOO', '...setting here...') настройки как FOO = getattr(settings, 'FOO', '...setting here...')

Плюсы: – значения по умолчанию всегда переопределены

Минусы:

  • Повторяющийся (должен определять var дважды – один раз в строковой форме, один раз в var)
  • Настройка не так читаема, так как теперь это третий аргумент

4: Создать функцию утилиты для get_or_default(setting)

Плюсы:

  • просто
  • Не нужно повторять строковое представление настроек

Минусы:

  • Должен называть это

5: Создайте класс настроек

 class Settings(object): FOO = 'bar' def __init__(self): # filter out the startswith('__') of # self.__dict__.items() / compare to django.conf.settings? my_settings = Settings() 

Минусы:

  • Невозможно сделать из foo.bar.my_settings import FOO (на самом деле, это ужасный разбойник!)

Я хотел бы услышать отзывы.

4 Solutions collect form web for “Стандарт по умолчанию для Django для подключаемого приложения?”

Я думаю, что довольно часто создавать settings.py в пакете вашего приложения, где вы определяете свои настройки следующим образом:

 from django.conf import settings FOO = getattr(settings, 'FOO', "default_value") 

В вашем приложении вы можете импортировать их из модуля settings вашего приложения:

 from myapp.settings import * def print_foo(): print FOO 

Но я думаю, что все согласны с тем, что для Django не хватает лучшей общей архитектуры! Если вы ищете более сложный способ справиться с этим, для этого, например, django-appconf , есть сторонние приложения, но это ваше решение, если вы хотите ввести еще одну зависимость для своего приложения или нет!

Как насчет этого?

В myapp / settings.py:

 from django.conf import settings FOO = 'bar' BAR = 'baz' _g = globals() for key, value in _g.items(): _g[key] = getattr(settings, key, value) 

В myapp / other.py:

 import myapp.settings print myapp.settings.FOO 

Учитывая этот ответ ncoghlan, я чувствую себя нормально, используя globals () таким образом.

Номер 3 является лучшим, потому что он самый простой. И очень последовательный взгляд.

Номер 1: его легко упускать. Если я открою ваш код, и я не прокручу его до конца, я пропущу его, и я подумаю, что настройки не могут быть переопределены в моем собственном модуле.

Номер 2: не только повторяется, его труднее читать, потому что он слишком длинный, и значения по умолчанию будут определены несколько раз и будут разбросаны по всему вашему коду.

Номер 4: непоследовательные, повторяющиеся вызовы.

Номер 5: Непоследовательно, мы ожидаем, что настройки будут определены в модуле не в классе. Ну, по крайней мере, я ожидаю, что это будет определено как модуль, потому что я видел много приложений, используя метод 3, и я использую его сам, поэтому я могу быть предвзятым.

В ответ на комментарий Фила Гифорда, подвергая проблеме настроек, не перезаписываемых в тестах (поскольку они уже были импортированы в модули), я сделал определение класса AppSettings в __init__.py с помощью:

  • метод __init__ для инициализации каждого параметра в None
  • метод load для загрузки всех настроек из геттеров
  • статические геттеры для каждой настройки

Затем в коде:

 from . import AppSettings def in_some_function(): some_setting = AppSettings.get_some_setting() 

Или если вы хотите загрузить их все один раз (но переопределяющие настройки в тестах не будут работать для затронутого модуля):

 from . import AppSettings app_settings = AppSettings() app_settings.load() def in_some_function(): print(app_settings.some_setting) 

Затем вы можете использовать декоратор override_settings в своих тестах и ​​все еще иметь некоторый СУХОЙ и понятный способ использования настроек приложения, за счет большего количества инструкций, выполняемых каждый раз, когда вы хотите получить настройку (только для тестов …).

Python - лучший язык программирования в мире.