Локальные настройки Django

Я пытаюсь использовать local_setting в Django 1.2, но он не работает для меня. На данный момент я просто добавляю local_settings.py к моему проекту.

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco1',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

local_settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco2',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

Проблема в том, что local_settings.py не переопределяет settings.py. Что не так?

Ответ 1

Вы не можете просто добавить local_settings.py, вам придется явно импортировать его.

В самом конце вашего settings.py добавьте следующее:

try:
    from local_settings import *
except ImportError:
    pass

Блок try/except существует, поэтому Python просто игнорирует случай, когда вы фактически не определили файл local_settings.

Ответ 2

Это лучшая практика, я думаю:

  • local_settings импорт из settings
  • local_settings переопределяет настройки, специфичные для локальной среды, особенно DATABASES, SECRET_KEY, ALLOWED_HOSTS и DEBUG variables
  • передать командам управления django флаг --settings=local_settings

Вы можете реализовать local_settings следующим образом:

from settings import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'banco2',                      # Or path to database file if using sqlite3.
        'USER': 'root',                      # Not used with sqlite3.
        'PASSWORD': '123',                  # Not used with sqlite3.
        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

Несколько дополнительных ключевых моментов:

  • settings.py находится в управлении версиями, написанном таким образом, что он готов к использованию вкладчиками
  • local_settings.py (или чаще prod_settings.py) НЕ находится в управлении версиями и используется в производстве, указав --settings=prod_settings или аналогичный.

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

Ответ 3

Поскольку тема resurfaces обычно позволяет мне подвести итог, почему вы, возможно, захотите рассмотреть этот подход:

  • немой файл настроек очень быстро и легко изменяется; особенно в производственной среде. Нет необходимости в python: любой идиот может впрыгнуть и изменить пароль базы данных в файле, который просто перечисляет имена и значения; особенно по сравнению с сложным файлом настроек python, полным таинственных опасных имен BIGCAPS.

  • приложение settings должно быть полностью отделено от приложения code. Вы можете поместить config.ini за пределы корня репозитория и никогда больше не беспокоиться о том, что репозиция вытащила ваши настройки, или ваши личные настройки, загрязняющие репо, или этот умный код в ваших настройках .py не превратить его в репо для всех остальных преимуществ.

Это не относится к небольшим проектам, но по более крупным проектам я пришел к выводу, что стратегия local_settings просто не сокращает его; с течением времени достаточно сложно программировать приложение, в котором ему сложно справиться; прежде всего, поскольку настройки становятся производными и/или взаимозависимыми. Могут быть хорошие оправдания для параметров, которые необходимо отреагировать в соответствии с локальными настройками, которые заставляют импортировать файл local_settings ползать вверх к середине settings.py. Я нахожу, что все начинает запутываться, когда это происходит.

Мое текущее решение заключается в использовании файла config, я дублирую его "local.ini". Он содержит только те значения, которые действительно изменяются между развернутыми экземплярами. Код отсутствует: это только значения и логические значения:

[global]
domain = 127.0.0.1:8000
database_host = 127.0.0.1
database_name = test_database
debug = Yes
google_analytics_id = UA-DEV-1
payments = testing
use_cdn = No

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

from ConfigParser import RawConfigParser
parser = RawConfigParser()

APPLICATION_ROOT = path.abspath(path.dirname(__file__))
parser.readfp(open(path.join(APPLICATION_ROOT, 'local.ini')))

# simple variables
DATABASE_HOST = parser.get('global', 'database_host')
DATABASE_NAME = parser.get('global', 'database_name')

# interdependencies
from version import get_cdn_version
CDN = 'd99phdomw5k72k.cloudfront.net'
if parser.getboolean('global', 'use_cdn'):
    STATIC_URL = '/{}/static/{}/'.format(CDN, get_cdn_version())
else:
    STATIC_URL = '/static/'


# switches
payments = parser.get('global', 'payments')
if payments == 'testing':
    PAYMENT_GATEWAY_ENDPOINT = 'https://api.sandbox.gateway.com'
else:
    PAYMENT_GATEWAY_ENDPOINT = 'https://api.live.gateway.com'

Если вы столкнулись с BOFH, как это было у меня однажды, он особенно взволновал способность удерживать local.ini в каталог /etc как /etc/ourapp.ini, и поэтому сохраните каталог приложения как чистый экспорт репозитория. Конечно, вы могли бы сделать это с помощью local_settings.py, но последнее, что он хотел сделать, это испортить код python. Простой конфигурационный файл, который он мог бы обрабатывать.

Ответ 4

Я сохранил копию __local_settings.py:

  • local_settings.py игнорируется в управлении версиями, но не __local_settings.py
  • update README.md, чтобы сообщить команде о том, как настроить: cp {__,}local_settings.py (которые делают копию для своих локальных настроек)

В прошлом

Я использовал эти параметры для импорта.

# settings.py
DATABASE = {...}

try:
    from .local_settings import *
except ImportError:
    pass

сейчас

Я просто импортирую настройки из local_settings.py.

И с помощью следующей команды: python manage.py runserver --settings=<proj>.local_settings.

# local_settings.py & __local_settings.py
from .settings import *

DATABASE = {...}

И поскольку, я обычно не взаимодействую с manage.py напрямую, потому что для меня явно необходимы некоторые параметры (например, address:port). Поэтому я ввел все эти команды в мой Makefile.

Например, здесь мой Makefile:

run:
    python manage.py runserver 0.0.0.0:8000 --settings=<proj>.local_settings

sh:
    python manage.py shell_plus --settings=<proj>.local_settings

dep:
    npm install
    pip install -r requirements.txt

Таким образом:

make dep
make sh 
make run

Заключение

Если вы используете не, используя Makefile в качестве рабочего процесса, вы можете использовать более ранний метод, но если вы используете make файл, то я считаю, что лучше быть более явным в вашем Makefile.

Ответ 5

Перед запуском сервера выполните

export DJANGO_SETTINGS_MODULE=appname.local_settings.py

и не забывайте делать

from settings import *

в файле local_settings.py

Ответ 6

Я нашел подобное решение. Это моя конфигурация для этого случая:

settings.py:

DEBUG = False

try:
    from local_settings import *

except ImportError:
    pass

if DEBUG is False:
    ALLOWED_HOSTS = ['sth.com']
    DATABASES = {
        ....
    }

local_settings.py:

from settings import *
ALLOWED_HOSTS = ['*']
DEBUG = True
DATABASES = {
    ...
}