Локальные Настройки 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. Что случилось?

7 64

7 ответов:

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

на конец вашего settings.py, добавьте это:

try:
    from local_settings import *
except ImportError:
    pass

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

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

  • local_settings импорт из settings
  • local_settings переопределяет параметры, характерные для локальной среды, особенно DATABASES,SECRET_KEY,ALLOWED_HOSTS и DEBUG переменные
  • перейти к командам управления 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 до следующей версии, посмотрите на разницу в запасе settings.py и ваш, и принимать меры по мере необходимости в зависимости от что изменилось. Изменения в значениях по умолчанию могут быть важны, и чем меньше вы коснулись оригинала settings.py файл, тем легче будет различить изменения вверх по течению.

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

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

  • приложение settings должны быть полностью отделены от приложения code. Можно поставить конфиг.ini вне корня репозитория и никогда больше не беспокоиться о том, что РЕПО вытянет ваши настройки, или ваши личные настройки загрязняют РЕПО, или этот умный код в вашем settings.py не делая это в репо к выгоде всех остальных.

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

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

[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 как и любой другой фрагмент кода приложения: настройте его, проверьте и разверните, не беспокоясь о тестировании против любого кода, который может скрываться в коде local_settings python. Мой 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/ourapp.ini и так держать приложение сам каталог - это чистый экспорт репозитория. Конечно, вы могли бы сделать это с помощью local_settings.py но последнее, что он хотел сделать, это возиться с кодом python. Простой конфигурационный файл, с которым он мог справиться.

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

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

в прошлом

я использовал для импорта этих настроек.

# 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 в качестве рабочего процесса, то вы можете использовать более ранний метод, но если вы используете makefile, то я считаю, что лучше быть более явным в вашем Makefile.

перед запуском сервера

export DJANGO_SETTINGS_MODULE=your_app_name.local_settings где your_app_name должно быть заменено именем вашего приложения. И не забудьте сделать

from settings import *

в вашем local_settings.py файл

еще один подход заключается в использовании python-dotenv и переменные среды для настройки параметров для различных сред.

создать .env file along-side your settings.py:

# .env
SECRET_KEY=your-secret-key
DATABASE_PASSWORD=your-database-password

добавить следующий код settings.py:

# settings.py
from dotenv import load_dotenv
load_dotenv()

# OR, explicitly providing path to '.env'
from pathlib import Path  # python 3.4+
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

в этот момент разбираются ключи / значения из .env файл присутствуют в качестве переменных среды, и они могут быть удобно доступны через os.getenv():

# settings.py
import os
SECRET_KEY = os.getenv('SECRET_KEY')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')   

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

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 = {
    ...
}