Невозможно использовать переменные среды для настроек в Django

При попытке найти место для хранения и сохранения настроек за пределами settings.py и базы данных я использовал environment.json для переменных среды. Я импортирую их в settings.py.

Моя проблема в том, что когда я пытаюсь изменить или сохранить новые значения в своей среде, env, settings.py не замечает изменения - возможно, потому, что время и количество раз settings.py читается Django.

Есть ли способ, которым я мог бы использовать переменные окружения так, как я хочу, например, как показано ниже?

# settings.py
import json
with open('/home/dotcloud/environment.json') as f:
    env = json.load(f)
EMAIL_HOST = env.get('EMAIL_PORT', '500')

# views.py
import json
def site_configuration(request):
    with open('/home/dotcloud/environment.json') as f:
        env = json.load(f)
    if request.method == 'POST':
        os.environ['EMAIL_PORT'] = request.POST['email_port']
    return render(request, ...)

# python manage.py shell demo
>>> import json
>>> with open('/home/dotcloud/environment.json') as f:
...     env = json.load(f)
... 
>>> project_settings.EMAIL_PORT
'500'
>>> env['EMAIL_PORT']
Traceback (most recent call last):
  File "<console>", line 1, in <module>
KeyError: 'EMAIL_PORT'
>>> env['EMAIL_PORT'] = "123"
>>> env['EMAIL_PORT']
'123'
>>> project_settings.EMAIL_PORT
'500'
>>> project_settings.EMAIL_PORT == env['EMAIL_PORT']
False'

А если нет, как еще я могу сохранить изменчивые настройки, которые извлекаются settings.py где-то в моем проекте Django?

Ответ 1

Возможно, вы захотите изучить foreman (GitHub) или honcho (GitHub). Оба они ищут файл .env в вашем текущем каталоге, из которого можно загрузить локальные переменные среды.

Мой .env выглядит так для большинства проектов (я использую dj-database-url для конфигурации базы данных):

DATABASE_URL=sqlite://localhost/local.db
SECRET_KEY=<a secret key>
DEBUG=True

В вашем файле settings.py вы можете загрузить эти настройки из os.environ следующим образом:

import os
DEBUG = os.environ.get('DEBUG', False)

Если есть необходимые настройки, вы можете assert их присутствие, прежде чем пытаться их установить:

assert 'SECRET_KEY' in os.environ, 'Set SECRET_KEY in your .env file!'
SECRET_KEY = os.environ['SECRET_KEY']

Я использую этот метод обработки локальных настроек для последних нескольких проектов, которые я начал, и я думаю, что он работает очень хорошо. Одно предостережение состоит в том, чтобы никогда не передавать ваш .env в исходное управление. Это локальные настройки, которые существуют только для текущей конфигурации и должны быть воссозданы для другой среды.

Ответ 2

Я вижу, что вопрос немного изменился, исходные ответы все еще ниже, но у этого есть немного другой ответ:


Сначала убедитесь, что вы используете правильные settings.py(print 'This file is being loaded' должен сделать трюк).

Во-вторых, лично я бы посоветовал не использовать json файлы для config, так как он менее динамичен, чем файлы Python, но он должен работать независимо.

Мой рекомендуемый способ сделать что-то вроде этого:

  • создайте файл base_settings.py со стандартными настройками
  • создайте settings.py, который будет импортироваться по умолчанию. Этот файл должен иметь from base_settings import * вверху, чтобы наследовать базовые настройки.
  • Если вы хотите иметь собственный файл настроек, dotcloud_settings.py, например, просто добавьте from dotcloud_settings import settings (или base_settings) и установите переменную окружения DJANGO_SETTINGS_MODULE на dotcloud_settings или your_project.dotcloud_settings в зависимости от вашего установка.

Обратите внимание, что вы должны быть очень осторожны при импорте модулей Django из этих файлов настроек. Если какой-либо модуль выполняет from django.conf import settings, он перестанет анализировать ваши настройки после этой точки.

Что касается использования json файлов, примерно такой же принцип, конечно:

  • Еще раз убедитесь, что у вас нет ничего, что импортирует django.conf.settings здесь
  • Сделайте все переменные в вашем json файле глобальными в файле настроек:

    import json с открытым ('/home/dotcloud/environment.json') как f:   env = json.load(f)   # Немного взломать все переменные в нашем env global   Глобал(). Обновление (окр)


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

Кроме того, Django по умолчанию не прослушивает переменные среды (кроме DJANGO_SETTINGS_MODULE, поэтому это может быть и проблема.