django-pkgconf

    rick-and-morty
    Rick and Morty ©. Чувак презентует батарейку, я тоже.


    Не так давно я опубликовал небольшое приложение для формирования «панелей управления» django-проектов. В процессе разработки столкнулся с банальной ситуацией хранения дефолтных настроек модуля. Скорый поиск по гитхабу дал понять, что каждый разработчик использует свою реализацию. Существуют также готовые решения, однако, мне они показались избыточными в таком простом вопросе, поэтому я поступил мудро и запилил свой велосипед.


    Может показаться, что данная батарейка будет полезна только OSP-шникам, но штука в том, что эту же самую идею можно использовать в повседневной жизни.


    «Банальная ситуация»


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


    Типа так:


    # Дефолтное значение в app/my_settings.py
    FOO = True
    
    # Вы ставите в settings.py
    FOO = False
    
    # В итоге, переписалось
    from django.conf import settings
    settings.FOO
    False
    

    Используем у себя в проекте


    Сейчас уже привычно разрабатывать проект модульно разбивая его на "приложения". Практически все вынесено в индивидуальные файлы аппы: models, views, urls… кроме settings. Например, вы пишете адаптер к сервису рассылок и следующий код в каком-нибудь newsletters/adapter.py:


    adapter = Adapter(username='user', password='pass')

    Вы будете правы, если скажете, что хардкодить логин и пароль глупо и их надо вынести в константы:


    USERNAME = 'user'
    PASSWORD = 'password'
    
    adapter = Adapter(username=USERNAME, password=PASSWORD)

    Вроде бы близко, но все равно не то. Еще подход:


    # settings.py
    NEWSLETTERS_USERNAME = 'user'
    NEWSLETTERS_PASSWORD = 'password'
    
    # newsletters/adapter.py
    from django.conf import settings
    adapter = Adapter(username=settings.NEWSLETTERS_USERNAME, password=settings.NEWSLETTERS_PASSWORD)

    Похоже на правду. Однако есть несколько "но":


    • вот это NEWSLETTERS_ не очень удобно. Во-первых, просто больше повторяющихся букв в коде; во-вторых, значения могут быть более универсальным и использоваться чаще, от чего эта причина становится все печальнее
    • эти настройки не относятся к проекту, но нужны для отдельного приложения и, вероятно, за его пределами не используются — так зачем их держать в основном файле?
    • если аппа разрабатывается одним человеком в комманде, его коммит ограничивается директорией приложения

    django-pkgconf


    Попробуем сделать так:


    # newsletters/conf.py
    from pkgconf import Conf
    class NewsLetters(Conf):
        USERNAME = 'username'
        PASSWORD = 'password'
    
    # newsletters/adapter.py
    from . import conf
    adapter = Adapter(username=conf.USERNAME, password=conf.PASSWORD)

    Условия выполнены: нет префикса, нет захламления файла настроек проекта.
    Переопределим значения в Dev настройках*:


    # local_settings.py
    NEWSLETTERS_USERNAME = 'test_user'

    Готово. Это перепишет значение USERNAME для конфигурации приложения newsletters, а значение PASSWORD останется прежним, потому что мы его не меняли. В результате получаем аккуратный и стройный settings.py, где лежат всякие там DATABASES, TEMPLATES и т.д., только то, что относится к проекту.


    Совместимость


    Тесты проводились на python 2.7.9, 3.4.3, 3.5.0 и django 1.8, 1.9.


    Name                  Stmts   Miss  Cover
    -----------------------------------------
    pkgconf/__init__.py      22      0   100%

    Проект на гитхабе.


    * Пожалуйста, не делайте так, используйте django-configurations.

    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 5
    • +2

      Есть еще аналог вашего приложения django-appconf, ставится вместе с django-compressor.
      Мне тогда понравилась эта идея для хранения настроек.

      • 0
        Да, его и еще одно я указал на странице проекта в разделе Powered Siblings. Может сейчас еще что найдется, пополню список.
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0

          Все-таки, как ни крути, а ini-файлы были одним из лучших средств хранения конфигурации среднеразмерных приложений. Все эти yaml'ы, plist'ы, json'ы, xml'и и, упаси Торвальдс, реестр (а ля реестр Windows или GConf) или хардкодинг значений в settings.py выглядят очень печально (т.е. я не спорю, в ряде случаев без них не обойтись, но все же ini гораздо читаемей, на мой взгляд).


          P.S. А в современном мире повальной контейнеризации и виртуализации стоит отметить вот такой подход: http://12factor.net/config.
          P.P.S. Спасибо за модуль, в рамках Django такой подход мне тоже очень нравится.

          • 0

            Добавил релиз 0.2.0


            • поддержка атрибута __prefix__ для кастомных префиксов, которые идут вразрез с pep8 (по-умолчанию берется имя класса, которое не может содержать подчеркивания)
            • поддержка методов и свойств (property) типа так:


              from pkgconf import Conf
              
              class MyEmailService(Conf):
                  USERNAME = 'username'
                  PASSWORD = 'password'
              
                  @property
                  def DEBUG(self):
                      return self.USERNAME.startswith('test_')

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Интересные публикации