Работа с несколькими модулями настроек

Работа с несколькими модулями настроек

S0mebody



Обычно рекомендуется избегать использования нескольких файлов конфигурации, а вместо этого упростить настройку проекта. Но это не всегда возможно, поскольку проект начинает расти, модуль settings.py может стать довольно сложным. В таких случаях вам также следует избегать использования операторов if, например if not DEBUG: # do something .... Для ясности и строгого разделения того, что является конфигурацией разработки и производственной конфигурацией, вы можете разбить модуль settings.py на несколько файлов.


Базовая структура

Совершенно новый Django проект выглядит так:

mysite/
 |-- mysite/
 |    |-- __init__.py
 |    |-- settings.py
 |    |-- urls.py
 |    +-- wsgi.py
 +-- manage.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 предоставит общие настройки для всех сред (разработка, производство, постановка и т. д.).


Следующим шагом будет создание модуля настроек для каждой среды. Распространенные варианты использования:

  • ci.py
  • development.py
  • production.py
  • staging.py

Структура файлов будет выглядеть так:

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


Настройка нового settings.py

Сначала возьмем в качестве примера следующий модуль base.py:

settings/base.py

from decouple import config

SECRET_KEY = config('SECRET_KEY')

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'mysite.core',
    'mysite.blog',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

WSGI_APPLICATION = 'mysite.wsgi.application'

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


Теперь, чтобы создаем модуль development.py, который расширяет наш модуль настроек base.py. Mы можем добиться этого следующим образом:

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

Обратите внимание на два важных момента: избегайте использования импорта звездочкой (import *). Это одно из немногих исключений. Импорт звездочки может поместить много ненужного в пространство имен, что в некоторых случаях может вызвать проблемы. Еще одна важная вещь: несмотря на то, что мы используем разные файлы для разработки и производства, вам все равно придется защищать конфиденциальные данные! Убедитесь, что вы храните пароли и секретные ключи в переменных среды или используйте библиотеку, такую ​​как Python-Decouple, которую я настоятельно рекомендую!


Как это использовать

Поскольку у нас больше нет settings.py в корне проекта, выполнение таких команд, как python manage.py runserver, больше не будет работать. Вместо этого вы должны указать, какой модуль settings.py вы хотите использовать в командной строке:

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

или

python manage.py migrate --settings=mysite.settings.production

Следующий шаг не является обязательным, но поскольку мы часто используем manage.py в процессе разработки, вы можете отредактировать его, чтобы установить модуль настроек по умолчанию для вашего модуля development.py.


Для этого просто отредактируйте файл manage.py:

manage.py

#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings.development")  # <-- Изменить здесь!
    try:
        from django.core.management import execute_from_command_line
    except ImportError:
        # Вышеупомянутый импорт может завершиться неудачно по какой-
        # либо другой причине.
        try:
            import django
        except ImportError:
            raise ImportError(
                "Couldn't import Django. Are you sure it's installed and "
                "available on your PYTHONPATH environment variable? Did you "
                "forget to activate a virtual environment?"
            )
        raise
    execute_from_command_line(sys.argv)

Итак, в основном мы изменили строку с:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

К:

os.environ.setdefault ("DJANGO_SETTINGS_MODULE", "mysite.settings.development")

Теперь вы можете снова запускать команды manage.py без использования аргумента --settings. Но не забудьте обратиться к модулю правильных настроек в производстве!


Некоторые вещи, которые вы можете сделать

Поскольку теперь у нас есть разные модули настроек, вы можете удалить AUTH_PASSWORD_VALIDATORS из файла settings/base.py и добавить его только в модуль settings/production.py. Таким образом, вы используете простые пароли, такие как "123" во время разработки, но в производственной среде они будут защищены валидаторами.


В ваших settings/tests.py или settings/ci.py вы можете переопределить следующую конфигурацию, чтобы ваши тесты выполнялись быстрее:

DATABASES['default'] = {
    'ENGINE': 'django.db.backends.sqlite3'
}

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.MD5PasswordHasher',
)


Выводы

Надеюсь, этот пост был вам чем-то полезен! Не забывайте использовать новые знания осторожно!

Report Page