/ django

О settings.py и хранении "секретных" настроек

Я уже писал о настройках в этом посте. Но в последнее время я пересмотрел свое мнение по поводу хранения настроек, мне кажется использование файла local_settings.py избыточно и ведет к лишнему копипасту при работе с проектом. В последнее время я перел к такому формату:

settings/
    __init__.py
     base.py
     local.py
     dev.py
     production.py
     test.py
     ….

Работает это так, все основные настройки хранятся в base.py и мы используем нужные настройки для нужного окружения, примеру local.py будет выглядеть вот так:

# -*- coding: utf-8 -*-
from .base import *

BASE_HOST = "http://mai-he-mai.com/"
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': ‘project', 
        'USER': 'root',
        'PASSWORD': '',  
        'HOST': 'localhost', 
        'PORT': ''
    }
}

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}


DEBUG = True
TEMPLATE_DEBUG = DEBUG
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

INSTALLED_APPS += ('debug_toolbar')

И для запуска тестового сервера нам нужно ввести команду:

python manage.py runserver --settings=project.settings.local

Теперь все конфигурационный файлы для всех окружений можно хранить в системе контроля версий, ненужно создавать лишних файлов в окружении.

Теперь можно плавно перейти к хранению секретных настроек, таких как SECRET_KEY, логин/пароль от бд, логин/пароль от почтового сервера и тд. Как мы все понимаем хранение это информации в контроле версий крайне не правильна, поэтому мне кажется лучше это хранить в системный переменных, для этого нужно задать нужную информацию в .bashrc, .bash_profile или .profile или если вы используете virtualenvs то достаточно дописать нужную информацию в bin/activate, к примеру мы хотим задать SECRET_KEY и пароль от БД:

export MY_SECRET_KEY=$)a7n&o80u!6y5t-+j
export MY_BD_PASS=qweasd

Как же получить доступ к этим настройка из django? Да все просто все это есть в модуле os:


import os

SECRET_KEY = os.environ[‘MY_SECRET_KEY']

Но это не очень красиво и нужно отлавливать ошибки, поэтому правильней написать функцию:


import os
from django.core.exceptions import ImpropelyConfigured

def get_env_setting(var):
try:
return os.environ[var]
excapt KeyError:
msg = u”Переменная %s не задана” % var
raise ImpropelyConfigured(msg)

SECRET_KEY = get_env_setting(‘MY_SECRET_KEY’)

Теперь все красиво и безопасно.