Работа с несколькими модулями настроек
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', )
Выводы
Надеюсь, этот пост был вам чем-то полезен! Не забывайте использовать новые знания осторожно!