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