Django-Admin.ru

settings.py в Django: основные настройки и как с ними работать

Django settings: что лежит в settings.py, как импортировать настройки, задать DJANGO_SETTINGS_MODULE, вызвать settings.configure() и разделить dev и prod.

Редакция Django-Admin.ru
· 18 мин чтения

Содержание · 12 разделов
  1. Что внутри settings.py после startproject
  2. Отличия Django 5.2 LTS и 6.x
  3. Ключевые настройки Django
  4. Как Django собирает настройки
  5. Как импортировать настройки: from django.conf import settings
  6. Почему не импортировать config.settings напрямую
  7. Свои настройки
  8. DJANGO_SETTINGS_MODULE и параметр —settings
  9. Настройки в отдельном скрипте: django.setup() и settings.configure()
  10. settings.configure(): Django без файла настроек
  11. Ошибка «Requested setting …, but settings are not configured»
  12. Переменные окружения: секреты вне кода
  13. Файл .env и django-environ
  14. Разделение настроек на dev и prod
  15. Проверка настроек: diffsettings и check —deploy
  16. diffsettings: что изменено относительно стандартных значений
  17. check —deploy: проверка перед продакшном
  18. Частые вопросы
  19. Как посмотреть значение настройки из консоли?
  20. Как вывести настройку в шаблоне?
  21. Как временно изменить настройку в тестах?
  22. Как указать настройки для pytest?
  23. Почему изменения в settings.py не применяются?
  24. Можно ли хранить настройки в YAML или JSON?
  25. Итог

Настройки Django (Django settings) — это обычный Python-модуль, чаще всего config/settings.py, в котором каждая переменная в верхнем регистре — отдельный параметр: DEBUG, DATABASES, INSTALLED_APPS. Какой модуль загрузить, Django узнаёт из переменной окружения DJANGO_SETTINGS_MODULE: её выставляют manage.py, wsgi.py и asgi.py. В коде приложения настройки читают через объект django.conf.settings:

from django.conf import settings

if settings.DEBUG:
    print(settings.TIME_ZONE)  # → UTC

Ниже — разбор settings.py, который создаёт startproject, ключевые настройки, способы указать модуль настроек, работа из отдельных скриптов, ошибка «settings are not configured», переменные окружения и разделение настроек для разработки и продакшна. Все примеры проверены на Django 6.1.2; отличия Django 5.2 LTS отмечены отдельно.

Что внутри settings.py после startproject

Команда django-admin startproject config . создаёт пакет config с файлом settings.py (как создать проект и что лежит в остальных файлах, рассказано в статье «Как создать проект Django»). Без комментариев и ссылок на документацию сгенерированный файл Django 6.1 выглядит так:

# config/settings.py
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'django-insecure-...'  # случайный ключ, свой в каждом проекте
DEBUG = True
ALLOWED_HOSTS = []

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

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 = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

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

LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True

STATIC_URL = 'static/'

MAILERS = {
    'default': {
        'BACKEND': 'django.core.mail.backends.console.EmailBackend',
    },
}

Шаблон рассчитан на локальную разработку: режим отладки включён, ключ записан прямо в коде, база — файл SQLite. Комментарий Quick-start development settings - unsuitable for production в оригинальном файле предупреждает об этом прямо.

Отличия Django 5.2 LTS и 6.x

  • Django 5.2 добавляет в конец файла DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' и не содержит MAILERS.
  • Django 6.0 больше не генерирует DEFAULT_AUTO_FIELD: BigAutoField стал значением по умолчанию.
  • Django 6.1 добавляет настройку почты MAILERS с консольным бэкендом — письма в разработке печатаются в терминал. Прежние EMAIL_BACKEND и другие EMAIL_* в 6.1 работают, но объявлены устаревшими.

Остальная часть шаблона в этих версиях совпадает.

Ключевые настройки Django

НастройкаЗа что отвечаетКогда менять
BASE_DIRПуть к корню проекта; от него строят пути к базе, шаблонам, статикеПри переносе настроек в пакет (см. ниже)
SECRET_KEYКлюч для подписи сессий, CSRF-токенов, ссылок сброса пароляПеред продакшном: новый ключ из переменной окружения
DEBUGРежим отладки: подробные страницы ошибок, раздача статики runserverВ продакшне всегда False
ALLOWED_HOSTSДомены, на запросы к которым отвечает сайтОбязательно при DEBUG = False
INSTALLED_APPSПодключённые приложения: встроенные, сторонние и своиПосле startapp и установки пакетов
MIDDLEWAREЦепочка обработчиков каждого запроса и ответаПри подключении WhiteNoise, CORS, debug-toolbar
ROOT_URLCONFМодуль с корневыми маршрутамиРедко — при переименовании пакета
TEMPLATESДвижок шаблонов, папки поиска, контекстные процессорыКогда нужна общая папка templates/
DATABASESПодключение к базе данныхПри переходе на PostgreSQL или MySQL
LANGUAGE_CODE, TIME_ZONEЯзык интерфейса и часовой поясСразу: 'ru' и, например, 'Europe/Moscow'
USE_TZХранить время в UTC с учётом часовых поясовНе выключайте без причины
STATIC_URL, STATIC_ROOTURL статики и папка, куда collectstatic собирает файлыSTATIC_ROOT — перед деплоем
MAILERS / EMAIL_*Отправка почтыПеред продакшном: SMTP вместо консоли

Подробности по отдельным группам — в профильных статьях: подключение базы разобрано в статье «Базы данных в Django», папки шаблонов и DIRS — в руководстве по шаблонам Django.

Для русскоязычного проекта первым делом меняют две строки:

LANGUAGE_CODE = 'ru'
TIME_ZONE = 'Europe/Moscow'

Админка и сообщения валидации станут русскими, а время в шаблонах и формах — московским. В базе при USE_TZ = True оно по-прежнему хранится в UTC.

Как Django собирает настройки

Django не ограничивается вашим файлом. Сначала он загружает значения по умолчанию из модуля django/conf/global_settings.py (там около 150 параметров), затем поверх них — ваш модуль. Поэтому в settings.py указывают только то, что отличается от стандартного поведения.

Из вашего модуля берутся только имена в верхнем регистре. Переменная items_per_page = 20 останется обычной переменной модуля, и settings.items_per_page вызовет AttributeError. Это удобно: временные переменные и импорты в settings.py не превращаются в настройки.

Поскольку settings.py — обычный Python-код, в нём можно вычислять значения, импортировать другие модули и читать переменные окружения. Синтаксическая ошибка в нём ломает запуск любой команды manage.py. А если одна настройка присвоена дважды, действует последнее присваивание.

Как импортировать настройки: from django.conf import settings

Во всём коде проекта — во view, моделях, формах, командах — настройки читают так:

from django.conf import settings

page_size = settings.BLOG_PAGE_SIZE

settings — объект-посредник, который при первом обращении загружает модуль из DJANGO_SETTINGS_MODULE и объединяет его со значениями по умолчанию. Импортировать из него отдельное имя нельзя:

from django.conf.settings import DEBUG
# → ModuleNotFoundError: No module named 'django.conf.settings'

Почему не импортировать config.settings напрямую

Строка from config import settings работает, но создаёт три проблемы:

  1. Нет значений по умолчанию. В модуле есть только то, что вы написали. Например, LANGUAGE_COOKIE_NAME доступен через django.conf.settings, а в config.settings его нет.
  2. Код привязан к одному файлу. Когда настройки разделят на dev.py и prod.py или запустят с параметром --settings, прямой импорт продолжит читать старый модуль, а не выбранный.
  3. Не работает подмена в тестах. Декоратор override_settings и фикстура settings из pytest-django меняют значения в django.conf.settings; прямой импорт этих изменений не видит.

Свои настройки

Для своего приложения можно завести собственные параметры. Имя — только в верхнем регистре, без совпадений со встроенными настройками Django:

# config/settings.py
BLOG_PAGE_SIZE = 20

Если приложение должно работать и без этой строки, читайте её со значением по умолчанию:

from django.conf import settings

page_size = getattr(settings, 'BLOG_PAGE_SIZE', 10)

Изменять настройки во время работы, например settings.DEBUG = True во view, нельзя: часть кода Django читает значения один раз при старте, и результат будет непредсказуемым. Единственное место для присваивания — модуль настроек. Для тестов есть override_settings (пример в разделе вопросов).

DJANGO_SETTINGS_MODULE и параметр —settings

DJANGO_SETTINGS_MODULE содержит путь к модулю настроек в формате импорта Python — через точки и без расширения: config.settings. Пакет config должен находиться в sys.path — обычно это так, если команда запускается из папки с manage.py.

После startproject переменную выставляют три файла:

# manage.py, config/wsgi.py, config/asgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

setdefault записывает значение, только если переменная ещё не задана. Поэтому значение из окружения всегда главнее того, что написано в файле, — на этом строится переключение настроек без правки кода.

Задать модуль для всех команд в текущем терминале:

Windows (PowerShell):

$env:DJANGO_SETTINGS_MODULE = "config.settings"
django-admin check

Windows (cmd):

set DJANGO_SETTINGS_MODULE=config.settings
django-admin check

macOS и Linux:

export DJANGO_SETTINGS_MODULE=config.settings
django-admin check

Для одной команды удобнее параметр --settings — он есть у manage.py и django-admin и имеет приоритет над переменной окружения:

python manage.py check --settings=config.settings.prod

Если модуль указан с ошибкой, команда завершится сразу:

ModuleNotFoundError: No module named 'config.settings_prod'

Проверьте имя модуля и то, что команда запущена из корня проекта. Если пакет лежит в другой папке, её добавляют в путь поиска параметром --pythonpath.

Настройки в отдельном скрипте: django.setup() и settings.configure()

Скрипт, запущенный обычным python script.py, ничего не знает о проекте. Чтобы использовать ORM, модели или шаблоны проекта, ему нужно указать модуль настроек и вызвать django.setup() — эта функция загружает настройки и регистрирует приложения:

# count_users.py — лежит рядом с manage.py
import os

import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()

from django.contrib.auth.models import User  # импорт моделей — только после setup()

print(User.objects.count())
python count_users.py
0

Если импортировать модели до django.setup(), скрипт упадёт с ошибкой django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. Для задач, которые запускаются регулярно, удобнее собственная команда manage.py — тогда Django сам выполнит всю инициализацию.

settings.configure(): Django без файла настроек

Когда проекта нет и нужна только часть Django — например, движок шаблонов или валидаторы в обычном скрипте, — настройки задают прямо в коде:

from django.conf import settings

settings.configure(DEBUG=True, TIME_ZONE='Europe/Moscow')

print(settings.configured)
print(settings.DEBUG, settings.TIME_ZONE)
print(settings.LANGUAGE_CODE)
True
True Europe/Moscow
en-us

Все параметры, которые вы не передали, берутся из значений по умолчанию — как LANGUAGE_CODE выше. Правила у configure() строгие:

  • вызывать до первого обращения к любой настройке;
  • вызывать только один раз — повторный вызов даёт RuntimeError: Settings already configured.;
  • не сочетать с DJANGO_SETTINGS_MODULE: используется что-то одно.

Если код может запускаться в обоих режимах, проверяйте флаг settings.configured перед вызовом. Для ORM и шаблонов из приложений после configure() всё равно нужен django.setup().

Ошибка «Requested setting …, but settings are not configured»

django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

Ошибка значит, что код обратился к настройке, а Django не знает, какой модуль загрузить. Вместо DEBUG в сообщении может стоять INSTALLED_APPS, DATABASES или любая другая настройка — та, к которой обратились первой. Частые причины:

  • Файл проекта запущен напрямую — python blog/views.py или кнопкой Run в IDE. Модули проекта не предназначены для самостоятельного запуска: работайте через python manage.py runserver, python manage.py shell или собственную команду.
  • Отдельный скрипт без инициализации. Добавьте в начало os.environ.setdefault(...) и django.setup(), как в примере выше.
  • Обычный python вместо python manage.py shell. В интерактивной консоли Python Django не настроен; manage.py shell выставляет модуль настроек сам.
  • Тесты через pytest без pytest-django или без указания DJANGO_SETTINGS_MODULE в его конфигурации (см. раздел вопросов).
  • Сторонний процесс — воркер Celery, планировщик, скрипт деплоя — запущен без переменной DJANGO_SETTINGS_MODULE в окружении.

Похожие по смыслу ошибки при неверно заполненных настройках:

СообщениеПричина
ImproperlyConfigured: The SECRET_KEY setting must not be empty.Ключ пустой — например, не задана переменная окружения
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.runserver с DEBUG = False и пустым ALLOWED_HOSTS
ModuleNotFoundError: No module named 'config.prod'Опечатка в DJANGO_SETTINGS_MODULE или --settings
KeyError: 'DJANGO_SECRET_KEY'os.environ[...] не нашёл обязательную переменную

Переменные окружения: секреты вне кода

Ключ, пароль от базы и признак отладки различаются между ноутбуком и сервером, а секреты не должны попадать в Git. Их читают из переменных окружения стандартным модулем os:

# config/settings.py
import os

SECRET_KEY = os.environ['DJANGO_SECRET_KEY']           # обязательная: без неё — KeyError при старте
DEBUG = os.environ.get('DJANGO_DEBUG', '') == '1'      # по умолчанию выключено
ALLOWED_HOSTS = [
    host for host in os.environ.get('DJANGO_ALLOWED_HOSTS', '').split(',') if host
]

os.environ['...'] для обязательных значений лучше, чем .get() с запасным значением: сервер не запустится с пустым ключом, а ошибка сразу назовёт переменную.

Важно: переменные окружения — всегда строки. bool(os.environ.get('DJANGO_DEBUG')) вернёт True и для строки 'False', потому что она непустая. Сравнивайте со строкой явно, как в примере выше.

Новый ключ для продакшна генерирует сам Django:

python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

Файл .env и django-environ

Python не читает файл .env сам: значения из него попадают в os.environ только через пакет. Варианты:

СпособЧто даётКогда выбрать
os.environНичего не устанавливать; переменные задаёт systemd, Docker или хостингПродакшн и небольшие проекты без .env
python-dotenvЗагружает .env в os.environ, приведение типов — вручнуюНужен только .env, остальное устраивает
django-environ.env, приведение типов, разбор строки подключения DATABASE_URLМного настроек разных типов, база задаётся одной строкой
python-decouple.env или .ini, приведение типов через параметр castНужен общий подход для Django и других Python-проектов

Пример с django-environ (pip install django-environ):

# .env — рядом с manage.py, добавьте его в .gitignore
DEBUG=on
SECRET_KEY=change-me-local-secret
ALLOWED_HOSTS=localhost,127.0.0.1
DATABASE_URL=postgres://django:secret@localhost:5432/mysite
# config/settings.py
from pathlib import Path

import environ

BASE_DIR = Path(__file__).resolve().parent.parent

env = environ.Env(DEBUG=(bool, False))  # тип и значение по умолчанию
environ.Env.read_env(BASE_DIR / '.env')

DEBUG = env('DEBUG')                    # 'on' → True
SECRET_KEY = env('SECRET_KEY')
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[])
DATABASES = {'default': env.db()}       # разбирает DATABASE_URL

Если обязательной переменной нет, django-environ сообщит об этом понятно: ImproperlyConfigured: Set the SECRET_KEY environment variable. Переменные, уже заданные в окружении, главнее значений из .env: read_env их не перезаписывает. Поэтому на сервере можно не класть .env, а передать переменные через systemd или Docker. Строка DATABASE_URL для PostgreSQL подробно разобрана в статье о подключении PostgreSQL к Django.

Разделение настроек на dev и prod

Есть два рабочих подхода.

Один файл и переменные окружения. Код настроек одинаков везде, различаются только значения в окружении. Это проще, хорошо сочетается с Docker и подходит большинству проектов: всё, что отличается, — это DEBUG, ключ, хосты, база и почта.

Пакет настроек. Когда окружения различаются не значениями, а составом — в разработке подключён django-debug-toolbar, в тестах быстрый хешер паролей, в продакшне логирование в файл и HTTPS-настройки, — settings.py превращают в пакет:

config/
├── __init__.py
├── asgi.py
├── urls.py
├── wsgi.py
└── settings/
    ├── __init__.py   # пустой
    ├── base.py       # бывший settings.py: общие настройки
    ├── dev.py
    └── prod.py

В base.py остаются общие настройки, а SECRET_KEY, DEBUG и ALLOWED_HOSTS переезжают в файлы окружений:

# config/settings/dev.py
from .base import *  # noqa: F403

DEBUG = True
SECRET_KEY = 'django-insecure-only-for-local-development'
ALLOWED_HOSTS = []
# config/settings/prod.py
import os

from .base import *  # noqa: F403

DEBUG = False
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
ALLOWED_HOSTS = os.environ['DJANGO_ALLOWED_HOSTS'].split(',')

Чтобы переход прошёл без сюрпризов:

  1. В base.py добавьте ещё один .parent к BASE_DIR: файл стал на уровень глубже, и без правки база db.sqlite3 окажется внутри config/.

    BASE_DIR = Path(__file__).resolve().parent.parent.parent
  2. В manage.py укажите 'config.settings.dev', в wsgi.py и asgi.py — 'config.settings.prod'.

  3. На сервере всё равно задайте DJANGO_SETTINGS_MODULE=config.settings.prod в окружении — иначе python manage.py migrate на сервере выполнится с настройками разработки.

Важно: если забыть поправить wsgi.py или asgi.py, они продолжат указывать на config.settings. Теперь это пустой пакет, и Django загрузит его без ошибки: команда check пройдёт, но в проекте не будет ни приложений, ни базы. Проверяйте каждый модуль явно: python manage.py check --settings=config.settings.prod.

Часто встречается и вариант с local_settings.py: файл не хранится в Git, импортируется в конце settings.py внутри try/except ImportError и переопределяет значения на конкретной машине. Он удобен для личных правок, но обязательные параметры лучше держать в отслеживаемых файлах или в документированных переменных окружения — иначе у двух разработчиков окажутся разные невидимые настройки.

Проверка настроек: diffsettings и check —deploy

diffsettings: что изменено относительно стандартных значений

python manage.py diffsettings

Команда печатает итоговые значения всех настроек, которые отличаются от значений по умолчанию, — уже после всех импортов, условий и чтения переменных окружения. Пометка ### ставится у имён, которых нет среди стандартных настроек Django (например, BASE_DIR или ваши собственные).

DEBUG = True
INSTALLED_APPS = ['django.contrib.admin', 'django.contrib.auth', ...]
ROOT_URLCONF = 'config.urls'  ###
SECRET_KEY = 'django-insecure-...'
TIME_ZONE = 'UTC'

Полезные параметры:

  • --all — показать все настройки, включая стандартные (они отмечаются ### в начале строки);
  • --default config.settings.dev — сравнить не со стандартными значениями, а с другим модулем;
  • --output unified — вывод в формате diff: старое значение с -, новое с +.

Сравнение продакшн-настроек с настройками разработки из примера выше:

python manage.py diffsettings --settings=config.settings.prod --default=config.settings.dev
ALLOWED_HOSTS = ['example.ru']
DEBUG = False
SECRET_KEY = '...'
SETTINGS_MODULE = 'config.settings.prod'

Совет: diffsettings выводит и секреты — ключ, пароли из DATABASES. Не прикладывайте его вывод в публичные issue и чаты.

check —deploy: проверка перед продакшном

python manage.py check --deploy

На свежем проекте Django 6.1 команда находит 8 проблем (вывод сокращён):

ERRORS:
?: (mail.E001) Your MAILERS setting uses a development-only email backend ...

WARNINGS:
?: (security.W004) You have not set a value for the SECURE_HSTS_SECONDS setting. ...
?: (security.W008) Your SECURE_SSL_REDIRECT setting is not set to True. ...
?: (security.W009) Your SECRET_KEY has less than 50 characters, ...
?: (security.W012) SESSION_COOKIE_SECURE is not set to True. ...
?: (security.W016) You have 'django.middleware.csrf.CsrfViewMiddleware' in your MIDDLEWARE, but you have not set CSRF_COOKIE_SECURE to True. ...
?: (security.W018) You should not have DEBUG set to True in deployment.
?: (security.W020) ALLOWED_HOSTS must not be empty in deployment.

Запускайте проверку с теми же настройками и переменными окружения, что и на сервере: --settings=config.settings.prod. По умолчанию команда завершается с ошибкой только при уровне ERROR; в CI добавьте --fail-level WARNING, чтобы сборка падала и на предупреждениях. Как закрыть каждое предупреждение — HTTPS за прокси, cookie, HSTS, SMTP для MAILERS, — разобрано в чек-листе статьи «Деплой Django: Gunicorn и Nginx».

Частые вопросы

Как посмотреть значение настройки из консоли?

Через shell проекта — он уже знает модуль настроек:

python manage.py shell -v 0 -c "from django.conf import settings; print(settings.TIME_ZONE)"

Параметр -v 0 убирает строку об автоимпорте объектов, которую Django 5.2+ печатает при запуске shell. Для обзора всех изменённых значений используйте diffsettings.

Как вывести настройку в шаблоне?

Объект settings в шаблоны не передаётся. Если значение нужно на многих страницах, напишите контекстный процессор и добавьте его путь в TEMPLATES[0]['OPTIONS']['context_processors']:

# config/context_processors.py
from django.conf import settings


def site(request):
    return {'SITE_NAME': settings.SITE_NAME}

После этого в любом шаблоне доступно {{ SITE_NAME }}. Передавайте только нужные значения, а не весь объект настроек, чтобы случайно не вывести секреты.

Как временно изменить настройку в тестах?

Декоратором или контекстным менеджером override_settings: значение меняется только внутри блока и возвращается после него.

from django.conf import settings
from django.test import override_settings

with override_settings(SITE_NAME='Тест'):
    print(settings.SITE_NAME)  # → Тест
print(settings.SITE_NAME)      # → Мой блог

В pytest-django то же делает фикстура settings.

Как указать настройки для pytest?

Установите pytest-django и пропишите модуль в pyproject.toml:

[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "config.settings"

Тогда pytest сам выполнит инициализацию, и ошибки «settings are not configured» не будет. Подробнее — в статье о тестировании Django с pytest.

Почему изменения в settings.py не применяются?

Настройки читаются один раз при запуске процесса. runserver перезапускается сам при сохранении файла, а Gunicorn, Uvicorn и воркеры Celery нужно перезапустить вручную. Если перезапуск не помог, проверьте три вещи: не присваивается ли настройка ещё раз ниже в файле, не переопределяет ли её переменная окружения и какой модуль реально загружен — его показывает строка SETTINGS_MODULE в выводе diffsettings.

Можно ли хранить настройки в YAML или JSON?

Django загружает настройки только из Python-модуля, но внутри него можно прочитать любой файл: например, загрузить JSON модулем json и присвоить значения переменным в верхнем регистре. На практике для параметров, которые меняются между окружениями, проще переменные окружения: их поддерживают Docker, systemd и любой хостинг без дополнительного кода.

Итог

settings.py — обычный Python-модуль: Django берёт из него переменные в верхнем регистре и накладывает их на стандартные значения. Модуль выбирают через DJANGO_SETTINGS_MODULE или параметр --settings, а в коде к настройкам обращаются только через from django.conf import settings. Для скриптов вне manage.py нужны DJANGO_SETTINGS_MODULE и django.setup(), без проекта — settings.configure(). Секреты и всё, что отличается между машинами, читайте из переменных окружения; пакет settings/ с base.py, dev.py и prod.py нужен, когда окружения различаются составом настроек. Перед деплоем сверьте итоговую конфигурацию командой diffsettings и запустите check --deploy.

Общий маршрут изучения фреймворка — в руководстве «Django для начинающих», а упаковка проекта с настройками из окружения в контейнер — в статье «Django в Docker».

  • #Django
  • #settings.py
  • #DJANGO_SETTINGS_MODULE
  • #Переменные окружения
  • #Конфигурация
↑ ↓ выборEnter открытьEsc закрыть