Как импортировать константу из settings django
Перейти к содержимому

Как импортировать константу из settings django

  • автор:

Как получить доступ к значению константы в settings.py

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

PAYMENT_VARIANTS = < 'redsys': ('payments_redsys.RedsysProvider', < 'merchant_code': '123456789', 'terminal': '1', 'shared_secret': 'aaaaaaaaaaaaaaaaaaaaaaaaaa', 'currency': '978', >) 

Я могу импортировать:

from django.conf import settings 

Но, как я могу получить доступ к значению поля ‘currency’ или другого на этом уровне.

Спасибо, с уважением,

Вы можете сделать, например, так:

from django.conf import settings if settings.DEBUG: # Do something 

В вашем случае это будет что-то вроде:

settings.PAYMENT_VARIANTS['redsys'] 

Вы можете получить доступ к словарю PAYMENT_VARIANTS, используя settings.PAYMENT_VARIANTS и получить доступ к ключу currency следующим образом

settings.PAYMENT_VARIANTS['redsys'][1]['currency] 

Константы для reusable app

Я хочу часть своих тегов, фильтров, утилит и т.п. поместить в reusable app. Но ему потребуется много констант. Реально много. Линий 100-200 кода может потребоваться под константы. В settings.py всего проекта я их помещать не хотел бы. Обычно все приложения все же в общий settings за настройками ходят. Но не хочется что-то: много их там, читаемость кода упадет. Тем более. что для подготовки части констант у меня используются функции. Скажите, пожалуйста, куда мне их поместить? И как потом импортировать?

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Написать reusable API для работы со связным списком структур
6. Имеем чистый С. Напишите reusable API для работы со связным списком структур. Структуры могу.

Передача данных из reusable компонента в класс из которого он вызывается
Занимаюсь реализацией компонента (дальше контрол) который нужно в дальнейшем использовать в разных.

Можно ли как-то переместить файлы app.xmal в папку и app.config?
Перемещаю файл app.xmal, но в итоге элементы перестают видеть свойства прописанные в этом файле.

1040 / 575 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1

Kifsif, можешь создать приложение common (где будут находиться часто используемые вещи), в нём файл constants.py , например

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Ошибка import App from ‘./app.vue’ — net::ERR_ABORTED 404
На строке import App from ‘./app.vue’ браузер выдаёт ошибку "net::ERR_ABORTED 404" в файле.

VS 2008, C#: 1 Error. Constructor on type ‘App.App.Forms.FormBase’ not found. в FormDerived [Design]
и это после того, как добавил в котструктор базовой формы параметр. теперь в design только ее и.

Resolved versions for app (XX.X.X) and test app (XX.X.X) differ
Добрый день. При сборке проекта с отключенным телефоном (для запуска) постоянно возникает ошибка.

Константы в выражении для дифференцирования
Необходимо символически продифференцировать функцию. В функции, помимо аргумента, присутствуют.

Multiple definition для константы
Есть некий заголовочный файл с набором констант, который нужен во многих классах: #ifndef.

Константы для всего проекта
Здравствуйте. Можно ли как нить объявить константы для всего проекта,не в классе. Или vb.net так.

Multiple definition для константы
Есть некий набор констант, который нужен во многих классах: #ifndef RCCCONSTS_H #define.

Антипаттерн settings.py

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

Сейчас я хочу понегодовать на паттерн «все настройки — в settings.py». Понятно, что популярность он набрал благодаря Django. Я то и дело встречаю в проектах, никак не завязанных на этот фреймворк ту же самую историю: большая кодовая база, маленькие, хорошенькие никак не связанные друг с другом компоненты, и нате вам: все дружно из произвольных мест лезут в волшебный недомодуль settings за своими константами.

Итак, почему же такой подход на мой взгляд отвратителен.

Проблемы с каскадными настройками

В проектах из реальной жизни, как правило, нужно минимум три набора настроек: чтобы погонять проект на localhost, чтобы запускать unittest’ы, и чтобы крутить всё на боевых серверах. При этом большая часть настроек обычно совпадает во всех случаях, а некоторые различаются.

Например, у вас используется MongoDB в качестве хранилища. В общем случае, коннектиться к ней нужно на localhost и использовать DB с именем my_project . Однако для запуска unittest’ов нужно брать DB с другим именем, чтобы не задеть боевые данные: скажем, unittests . А в случае продакшена коннектиться нужно не на localhost, а на вполне определённый IP, на сервер, отданный под монгу.

Так как же, в зависимости от внешних условий settings.MONGODB_ADDRESS из settings.py должна принимать различные значения? Обычно в ход идёт voodoo-конструкция в конце, состоящая из __import__ , __dict__ , vars() , try/except ImportError , которая пытается дополнить и перекрыть пространство имён всеми потрохами другого модуля вроде settings_local.py.

То, что дополнительно нужно подгружать именно _local.py задаётся или хардкодом или через переменную окружения. В любом случае, чтобы те же например unittest’ы включили свои настройки только на время запуска приходится плясать с бубном и нарушать Zen of Python: Explicit is better than implicit.

Кроме того, такое решение сопряжено с другой проблемой, описанной далее.

Исполняемый код

Хранить настройки в виде исполняемого py-кода — жутко. На самом деле весь паттерн, видимо, изначально появился как якобы простое и элегантное решение: «А зачем нам какие-то cfg-парсеры, если можно сделать всё прям на питоне? И возможностей ведь больше!». В сценариях чуть сложнее тривиальных решение оборачивается боком. Рассмотрим, например, такой сниппет:

# settings.py BASE_PATH = os.path.dirname(__file__) PROJECT_HOSTNAME = 'localhost' SOME_JOB_COMMAND = '%s/bin/do_job.py -H %s' % (BASE_PATH, PROJECT_HOSTNAME) # settings_production.py PROJECT_HOSTNAME = 'my-project.ru' 

Понимаете в чём проблема? То, что мы перекрыли значение PROJECT_HOSTNAME абсолютно по барабану для итогового значения SOME_JOB_COMMAND . Мы могли бы скрипя зубами скопипастить определение SOME_JOB_COMMAND после перекрытия, но даже это не возможно: BASE_PATH то, в другом модуле. Копипастить и его? Не слишком ли?

Я уже не говорю о том, что исполняемый код в качестве конфигурации может просто приводить к трудноотлаживаемым ImportError при старте приложения в новой среде.

Поэтому я уверен, что мухи должны быть отдельно, котлеты отдельно: базовые значения в текстовом файле, вычисляемые — в py-модуле.

High-coupling

Хороший проект — тот проект, который возможно разобрать на маленькие кубики, а каждый кубик выложить на github в качестве полноценного open-source проекта.

Когда всё так и есть, но с одним НО: «будьте добры иметь settings.py в корне проекта и чтобы в нём были настройки FOO_BAR , FOO_BAZ и FOO_QUX » выглядит это как-то нелепо, не правда ли? А когда что-то звучит нелепо, обычно это означает, что есть ситуации в которых эта нелепость аукается.

В нашем случае, пример не заставляет долго себя выдумывать. Пусть наше приложение работает с VKontakte API, и у нас есть нечто вроде VKontakteProfileCache , которое в лоб пользуется settings.VK_API_KEY и settings.VK_API_SECRET . Ну пользуется и пользуется, а потом раз, и наш проект должен начать работать сразу с несколькими VKontakte-приложениями. А всё, VKontakteProfileCache спроектирован так, что он работает только с одной парой credentials.

Поэтому стройнее и целесообразнее вообще никогда не обращаться к модулю настроек напрямую. Пусть все потребители принимают нужные настройки через параметры конструктора, через dependency injection framework, как угодно, но не напрямую. А конкретные настройки пусть вытягивает самый-самый нижний уровень вроде кода в if __name__ == ‘__main__’ . А откуда уж он их возьмёт — его личные проблемы. При таком подходе также крайне упрощается unit-тестирование: с какими настройками нужно прогнать, с теми и создаём.

Возможное решение

Итак, паттерн «settings.py» грязью я полил. Мне полегчало, спасибо. Теперь о возможном решении. Я использовал подобный подход в нескольких проектах и нахожу его удобным и лишённым перечисленных проблем.

Настройки храним в текстовых ini-style файлах. Для парсинга используем ConfigObj: он имеет более богатые возможности по сравнению со стандартным ConfigParser, в частности с ним очень просто делать каскады.

В проекте заводим базовый файл настроек default_settings.cfg со всеми возможными настройками и их значениями с разумным умолчанием.

Создаём модуль utils.config с функциями вроде configure_from_files() , configure_for_unittests() , которые возвращают объект с настройками под разные ситуации. configure_from_files() организовывает каскадный поиск по файлам: default_settings.cfg , ~/.my-project.cfg , /etc/my-project.cfg и, вероятно, где-то ещё. Всё зависит от проекта.

Вычисляемые настройки эвалюируются последним шагом сборки объекта-конфигурации.

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

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

  • архитектура
  • django
  • паттерны проектирования
  • dependency injection
  • конфигурация

Глобальные константы в Django

Всем привет! Перехожу с богомерзкого php на великолепный python. Как следствие осваиваю django 🙂 И вот есть вопрос: хочу хранить путь к каталогу проекта как глобальную переменную (код из файла settings.py)

PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) PROJECT_ROOT = os.path.normpath(os.path.abspath(PROJECT_ROOT)) 

При попытке вызвать оную константу из файла app/modules.py получаю:

NameError: name ‘PROJECT_ROOT’ is not defined

Умные дяди, подскажите маленькому: как хранить глобальные константы?
Отслеживать
задан 5 дек 2011 в 11:53
158 1 1 серебряный знак 6 6 бронзовых знаков
код вызова пожалуйста покажите, settings.py — подключен?
5 дек 2011 в 11:56

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

from django.conf.settings import PROJECT_ROOT 

Отслеживать
ответ дан 5 дек 2011 в 12:07
3,028 13 13 серебряных знаков 14 14 бронзовых знаков
Модуль config, которого не было? from django.conf import settings
10 апр 2015 в 18:23

С точки зрения безопасности глобальные переменные — плохая идея. В то же время вы всегда можете использовать

from proj_name.settings import your_var 

Это позволит разделять пространство имён и использовать удобные для Вас переменные в нужном месте.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *