Разделение настроек Django для разработки и рабочего проекта

lepiloff

Feb. 28, 2018, 2:18 p.m.

Стандартная структура джанговского проекта содержит один файл настроект settings.py и обычно выглядит так:

mysite/
 |-- mysite/
 |    |-- __init__.py
 |    |-- settings.py
 |    |-- urls.py
 |    +-- wsgi.py
 +-- manage.py

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

Первым делом, создадим рядом с файлом settings.py папку settings и переместим в нее наш файл settings.py, предварительно переименовав его в base.py. Не забываем создать в папке пустой файл __init__.py. Получаем новую структуру:

mysite/
 |-- mysite/
 |    |-- __init__.py
 |    |-- settings/         <--
 |    |    |-- __init__.py  <--
 |    |    +-- base.py      <--
 |    |-- urls.py
 |    +-- wsgi.py
 +-- manage.py

Файл base.py будет содержать общие для всех окружений (рабочий проект и разработка). 

Следующим этапом создадим в папке settings отдельные файлы настроек и сконфигурируем их для разных проектов. Обычно принято называть их development.py и production.py. Теперь файловая структура будет выглядеть так:

mysite/
 |-- mysite/
 |    |-- __init__.py
 |    |-- settings/
 |    |    |-- __init__.py
 |    |    |-- base.py
 |    |    |-- development.py
 |    |    |-- production.py
 |    |-- urls.py
 |    +-- wsgi.py
 +-- manage.py

Конфигурируем настройки новых файлов 

Вот как выглядит главный файл настроек на одном из моих проектов (часть настроект намеренна упущена, чтобы не получился слишком большой вывод):

settings/base.py

import os
from decouple import config

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

SECRET_KEY = config('SECRET_KEY')

INSTALLED_APPS = [
    
    'django.contrib.admin',
    'django.contrib.auth',
   ......

]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...
    ...
]

ROOT_URLCONF = 'site.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
               .......
            ],
        },
    },
]

WSGI_APPLICATION = 'site.wsgi.application'

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    ...
    ...
]

Теперь займемся файлом development.py. В самом верху выполним импорт общих настроек и добавим конфигурационные переменный, необходимые только для разработки. 

settings/development.py

from .base import *

DEBUG = True

INSTALLED_APPS += [
    'debug_toolbar',
]

MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware', ]

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

DEBUG_TOOLBAR_CONFIG = {
    'JQUERY_URL': '',
}

Переходим к production.py

settings/production.py

from .base import *

DEBUG = False

ALLOWED_HOSTS = ['mysite.com', ]

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_PORT = 587
EMAIL_HOST_USER = config('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD')
EMAIL_USE_TLS = True

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Теперь сервер на локальном компьютере запускается командой:

python manage.py runserver --settings=mysite.settings.development

Только еще один нюанс - переместив файлы настроек в новую папку settings мы изменили уровень вложенности и теперь путь к корню изменился. Поэтому изменим в base.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

на

BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 

Для того, чтобы произведенные настройки возымели действие на рабочем сервере добавим в файл __init__.py в папке settings следующие строки:

from .production import *

try:
    from .local import *
except:
    pass

Вот собственно и все. В итоге мы разделили файлы настроек одного проекта для разных задач. Не лишним будет добавить наш файл development.py в .gitignore.

django