Рубрики
Без рубрики

Понять Джанго: понимание настроек

В последнем понимании статьи Django мы рассмотрели концепцию хранения в Django под названием Sessions …. Tagged с Python, Django, настройками.

Поймите Джанго (16 серии деталей)

В последнем Понять Джанго Статья, мы рассмотрели концепцию хранения в Джанго под названием «Сессии». Сессии помогают нам ответить на такие вопросы, как «Откуда узнает Джанго, когда пользователь вошел в систему?» или “Где может хранить данные Framework для посетителя в вашем приложении?”

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

Как настроен Джанго?

Чтобы правильно работать, Джанго должен быть настроен. Нам нужно понять, откуда взялась эта конфигурация. У Django есть возможность использовать значения или значения конфигурации по умолчанию, установленные такими разработчиками, как вы, но откуда они их получают?

В начале начала приложения Django Django внутренне импортирует следующее:

from django.conf import settings

Это Настройки Импорт – это объект уровня модуля, созданный в django/conf/__ init__.py . Настройки Объект имеет атрибуты, добавленные к нему из двух основных источников.

Первый источник – это набор глобальных настроек по умолчанию, которые поступают из фреймворка. Эти глобальные настройки от django/conf/global_settings.py и предоставить набор начальных значений для конфигурации, для которой Джанго должен работать.

Второй источник настроек конфигурации поступает из пользовательских значений. Django примет модуль Python и применит атрибуты уровня модуля к Настройки объект. Чтобы найти пользовательский модуль, Django ищет Django_settings_module переменная среды.

Боковая панель: переменные среды

Переменные среды не являются концепцией Джанго. Когда любая программа работает на компьютере, операционная система предоставляет определенные данные, доступные для программы работает. Этот набор данных называется «среда» программы, и каждая часть данных в этом наборе является переменной среды.

Если вы начинаете Django с терминала, вы можете просмотреть переменные среды, которые Django получит от операционной системы, запустив env Команда на MacOS или Linux, или установить команда в Windows.

Мы можем добавить наши собственные переменные среды в окружающую среду с Экспорт Команда на MacOS или Linux, или установить команда в Windows. Переменные среды обычно названы во всех заглавных буквах.

$ export HELLO=world

Теперь, когда у нас есть базовое понимание переменных среды, давайте вернемся к Django_settings_module переменная. Значением переменной должно быть местоположение модуля Python, содержащего любые настройки, которые разработчик хочет изменить от значений по умолчанию Джанго.

Если вы создаете проект Django с StartProject и использовать Проект В качестве имени вы найдете сгенерированный файл с именем Project/settings.py в выводе. Когда Джанго работает, вы можете явно обучить Джанго:

$ export DJANGO_SETTINGS_MODULE=project.settings

Вместо того, чтобы поставлять путь файла, Django_settings_module должен быть в пунктирной нотации модуля Python.

Вам не нужно на самом деле устанавливать Django_settings_module явно. Если вы придерживаетесь того же файла настроек, который создается StartProject , вы можете найти строку в wsgi.py это похоже на:

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

Из -за этой строки Джанго попытается прочитать из Project.Settings (или как бы вы назвали свой проект) без необходимости явно установить Django_settings_module Анкет

После того, как Django читает глобальные настройки и любые настройки, определенные пользователем, мы можем получить любую конфигурацию из Настройки объект через доступ к атрибуту. Это соглашение о сохранении всей конфигурации в Настройки Объект – это удобный шаблон, который фреймворк, экосистема сторонней библиотеки и ты может зависеть.

$ ./manage.py shell
>>> from django.conf import settings
>>> settings.SECRET_KEY
'a secret to everybody'

Настройки Объект – это общий элемент, поэтому, как правило, считается действительно плохой идеей ™ для редактирования и назначения объекту напрямую. Держите настройки в модуле настроек!

Это ядро конфигурации Django. Мы готовы сосредоточиться на настроенных пользователях и наших обязанностях в качестве разработчиков приложений Django.

Паттерны модуля настроек

Существует несколько способов справиться с модулями настроек и того, как заполнить эти модули соответствующими значениями для разных сред. Давайте посмотрим на некоторые популярные узоры.

Несколько модулей на среду

Модуль настроек Django – это модуль Python. Ничто не мешает нам использовать полную мощность Python для настройки этого модуля так, как мы хотим.

Минимально, у вас, вероятно, будет как минимум две среды, в которых работает ваше приложение Django:

  • На вашей местной машине во время развития
  • В Интернете Для вашего живого сайта

Мы должны знать, что настройка Отладка Это ужасная идея для живого сайта Django, так как мы можем получить преимущества режима отладки, не имея Отладка установить в Истинный в нашем модуле?

Одним из методов является использование отдельных модулей настроек. С помощью этой стратегии вы можете выбрать, какую среду ваше приложение Django должно работать, переключив Django_settings_module ценность, чтобы выбрать другую среду. У вас могут быть такие модули, как:

  • project.settings.dev
  • Project.Settings.Stage
  • Project.Settings.Production

Эти примеры были бы для местной среды разработки на вашем ноутбуке, для промежуточной среды (которая является общепринятой шаблоном для тестирования сайта, который как можно более похож на живой сайт без производственная среда. В качестве напоминания из статьи о развертывании, индустрия программного обеспечения любит называть основной сайт для клиентов «производством».

Эта стратегия имеет определенные проблемы для рассмотрения. Должны ли вы повторять настройки в каждом файле или использовать какой -то общий модуль между ними?

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

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

Если вы решите использовать общий модуль, этот стиль часто реализуется с помощью * импорт. С одной стороны, я могу рассчитывать количество мест, где я в порядке с * импорт, и это один из них. В большинстве случаев сообщество Python предпочитает явное из -за неявного, и эта идея распространяется на лечение импорта. Явный импорт дает понять, что на самом деле использует модуль. * Импорт очень неявный, и он неясно, что использует модуль. Для случая общего модуля настроек, a * Импорт на самом деле положительный, потому что мы хотим использовать Все в общем модуле.

Давайте сделаем это более конкретным. Предположим, что у вас есть Project.Settings.base модуль. Этот модуль будет держать ваши общие настройки для вашего приложения. Я бы порекомендовал вам попытаться сделать ваши настройки безопасными и безопасными по умолчанию. Например, используйте Отладка В базовых настройках и вынуждают другие модули настроек принять участие в более небезопасном поведении.

Для вашей местной среды разработки на вашем ноутбуке вы можете использовать Project.settings.dev Анкет Этот модуль настроек будет выглядеть как:

# project/settings/dev.py

from project.settings.base import *

DEBUG = True

# Define any other settings that you want to override.
...

С помощью * импорт в dev.py Файл, все настройки из base.py втянуты в объем уровня модуля. Где вы хотите, чтобы настройка отличалась, вы устанавливаете значение в dev.py Анкет Когда Джанго начинает использовать Django_settings_module из Project.settings.dev , все значения от base.py будет использоваться через dev.py Анкет

Эта схема дает вам контроль над тем, чтобы определить общие вещи один раз, но в этом все еще есть большая проблема. Что мы делаем в настройках, которые должны храниться в секрете (например, клавиши API)?

Не совершайте секретных данных в хранилище кода! Добавление секретов к вашему инструменту управления источником, таким как GIT, обычно не очень хорошая идея. Это особенно верно, если у вас есть публичный хранилище на GitHub. Думаете, никто не обращает внимания на ваше репо? Подумай еще раз! Есть инструменты, которые сканируют Каждый общественный коммит Сделано в GitHub. Эти инструменты специально ищут секретные данные для эксплуатации.

Если вы не можете безопасно добавить секреты в свой репо, где мы можем добавить их вместо этого? Вы можете использовать переменные среды! Давайте посмотрим на другую схему управления настройками с переменными среды.

Настройки через переменные среды

В Python вы можете получить доступ к переменным среды через ОС модуль. Модуль содержит среда Атрибут, который функционирует как словарь.

Используя переменные среды, ваш модуль настроек может получить настройки конфигурации из внешней среды, которая запускает приложение Django. Это солидный рисунок, потому что он может выполнить две вещи:

  • Секретные данные могут быть удержаны от вашего кода
  • Различия конфигурации между средами можно управлять путем изменения значений переменных среды

Вот пример секретного управления данными:

# project/settings.py

import os

SECRET_KEY = os.environ['SECRET_KEY']

...

Джанго нужен секретный ключ для различных целей безопасного хэширования. В дефолте есть предупреждение StartProject вывод, который читает:

# SECURITY WARNING: keep the secret key used in production secret!

Перемещая значение секретного ключа в переменную среды, которая имеет соответствующее имя СЕКРЕТНЫЙ КЛЮЧ , мы не будем совершать ценность для контроля источника для какого -то гнусного актера, чтобы обнаружить.

Этот шаблон очень хорошо работает для секретов, но он также может хорошо работать для любой Конфигурация, которую мы хотим варьироваться между средами.

Например, в одном из моих проектов я использую превосходное AnyAil Пакет для отправки электронных писем через поставщика услуг по электронной почте (из ESP, я случайно использую sendgrid ). Когда я работаю со своей средой разработки, я не хочу отправлять настоящую электронную почту. Из -за этого я использую переменную среды, чтобы установить Django’s Email_backend параметр. Это позволит мне переключаться между бэкэнд в любой почве и встроенным встроенным джанго django.core.mail.backends.console. Электронная почта Вместо этого печатает электронные письма на терминал.

Если я сделал эту конфигурацию электронной почты с Os.environ , это было бы похоже на:

# project/settings.py

import os

EMAIL_BACKEND = os.environ.get(
    'EMAIL_BACKEND', "anymail.backends.sendgrid.EmailBackend")

...

Я предпочитаю, чтобы мои настройки по умолчанию были ближе к контексту живого сайта. Это не только приводит к более безопасному поведению (потому что мне приходится явно отказаться от более безопасных настроек, таких как переход на Debug ), но также означает, что мой живой сайт имеет меньше настройки. Это хорошо, потому что есть меньше шансов сделать ошибки на конфигурации на сайте, что наиболее важно: тот, где находятся мои клиенты.

Нам нужно знать о большой Gotcha с использованием переменных среды. Переменные среды доступны только как str тип. Это то, что нужно знать, потому что будут времена, когда вы захотите логическое значение настройки или какое -то другое Тип данных. В ситуации, когда вам нужен другой тип, вы должны принудить str в тот тип, который вам нужен. Другими словами, не забывайте, что каждая строка, кроме пустой строки, является правдой в Python:

>>> not_false = "False"
>>> bool(not_false)
True

В следующем разделе мы увидим инструменты, которые помогут облегчить эту проблему печати.

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

Инструменты управления настройками

Мы можем сосредоточиться на двух категориях инструментов, которые могут помочь вам управлять вашими настройками в Django: встроенные инструменты и сторонние библиотеки.

Встроенный инструмент, который вам доступен,-это различия командование Этот инструмент позволяет легко увидеть вычисленные настройки вашего модуля. Поскольку настройки могут поступать из нескольких файлов (включая Django’s global_settings.py ) или переменные среды, осматривая вывод настройки различия удобнее, чем продумать, как установлена настройка.

По умолчанию, различия покажет сравнение модуля настроек с настройками Django по умолчанию. Настройки, которых нет в дефолте, отмечены ### После значения, чтобы указать, что они разные.

Я считаю, что выход по умолчанию не является наиболее полезным режимом. Вместо этого вы можете наставлять различия для вывода в «унифицированном» формате. Этот формат больше похож на код Diff. Кроме того, Django раскрашивает этот вывод, так что его легче увидеть. Вот пример некоторых настроек безопасности, работая ./manage.py diffsettings - -output Unified Для одного из моих проектов.

- SECURE_HSTS_INCLUDE_SUBDOMAINS = False
+ SECURE_HSTS_INCLUDE_SUBDOMAINS = True
- SECURE_PROXY_SSL_HEADER = None
+ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

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

$ ./manage.py diffsettings \
    --default project.settings.dev \
    --settings project.settings.prod \
    --output unified

С помощью -Дело Флаг, мы обучаем Джанго, что Project.settings.dev это базовая линия для сравнения. Эта версия команды покажет, где различаются два модуля настройки.

Django включает только этот единственный инструмент для работы с настройками, но я надеюсь, что вы увидите, что он действительно удобен. Теперь давайте поговорим о полезной сторонней библиотеке, которая может помочь вам с настройками.

Ранее в этой статье я отметил, что дело с переменными окружающей среды имеет ловушку, работая со строковыми данными для всего. К счастью, есть пакет, который может помочь вам работать с переменными окружающей среды. Проект называется Django-environ Анкет Django-environ в первую очередь делает две важные вещи, которые я ценю:

  • Пакет позволяет вам принуждать строки в желаемый тип данных.
  • Пакет будет читать из файла для загрузки переменных среды в вашу среду.

Как выглядит принуждение типа? С Django-environ , вы начинаете с Env объект.

# project/settings.py

import environ

env = environ.Env()

Ключевое слово аргументы к Env Опишите различные переменные среды, которые, как вы ожидаете, обработает приложение. Ключ – это имя переменной среды. Значение – это два элемента. Первый элемент кортежа – это тот тип, который вы хотите, а второй элемент – это значение по умолчанию, если переменная среды не существует.

Если вы хотите иметь возможность контролировать Отладка Из переменной среды настройки будут:

# project/settings.py

import environ

env = environ.Env(
    DEBUG=(bool, False),
)

DEBUG = env("DEBUG")

С помощью этой настройки ваше приложение будет безопасно по умолчанию с Отладка установить в Ложный В Но вы сможете переопределить это через окружающую среду. Django-environ Работает с горсткой струн, которые он примет как Верно такие как «on», «да», «истинность» и другие (см. Документацию для более подробной информации).

После того, как вы начнете использовать переменные среды, вам понадобится удобный способ установить их, когда ваше приложение работает. Вручную звонить Экспорт Для всех ваших переменных перед запуском вашего приложения является совершенно неустойчивым способом запуска приложений.

Env Класс поставляется с удобным методом класса с именем read_env Анкет С помощью этого метода ваше приложение может читать переменные среды в Os.environ из файла. Традиционно, этот файл назван .env , а также Файл содержит список паров ключей/значений, которые вы хотите в качестве переменных среды. После нашего предыдущего примера, вот как мы могли бы установить наше приложение в режиме отладки:

# .env
DEBUG=on

Вернувшись в файл настроек, вы включите read_env :

# project/settings.py

import environ

environ.Env.read_env()
env = environ.Env(
    DEBUG=(bool, False),
)

DEBUG = env("DEBUG")

Если вы используете .env Файл, вы иногда найдете необходимость вкладывать секреты в этот файл для тестирования. Поскольку файл может быть источником секретов, вы должны добавить это в .gitignore Или игнорируйте его в любой системе управления версией, которую вы используете. Со временем список переменных и настроек, вероятно, будет расти, поэтому он также является общим шаблоном для создания .env.Example Файл, который вы можете использовать в качестве шаблона на случай, если вам когда -либо нужно начать со свежего клона вашего репозитория.

Мои предпочтительные настройки настройки

Теперь мы рассмотрели несколько стратегий и инструментов для управления настройками. Я использовал многие из этих схем на различных проектах Django, поэтому Какова моя предпочтительная настройка?

Для большинства применений я нахожу, что работа с Django-environ В одном файле лучший шаблон в моем опыте.

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

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

$ EMAIL_TESTING=on ./manage.py runserver

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

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

Когда я запускаю свои модульные тесты, я хочу гарантировать, что определенные условия всегда верны. Есть вещи, которые тестовый набор никогда не должен делать в подавляющем большинстве случаев. Отправка реальных электронных писем – хороший пример. Если мне случится настроить мой .env Чтобы проверить реальные электронные письма для местной среды, я не хочу, чтобы мои тесты случайно отправляли электронные письма.

Таким образом, я создаю отдельный файл настроек тестирования и настраиваю свой тестовый бегнер (Pytest) для использования этих настроек. Этот файл настроек делает В основном используйте базовую среду, но я переопределяю некоторые настройки с явными значениями. Вот как я защищаю себя от случайных живых электронных писем:

# project/testing_settings.py

from .settings import *

# Make sure that tests are never sending real emails.
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"

Хотя мой Env Будет искать Email_backend Переменная среда Для динамической настройки настройки настройки тестирования жестко кодируются, чтобы сделать невозможным аварий по отправке по электронной почте.

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

Резюме

В этой статье вы узнали о настройках Django и о том, как управлять конфигурацией вашего приложения. Мы покрыли:

  • Как настроен Джанго
  • Шаблоны для работы с настройками в ваших проектах
  • Инструменты, которые помогают вам наблюдать и управлять настройками

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

  • Как модели Django поддерживают ссылки на файлы
  • Как файлы управляются в Джанго
  • Пакеты, которые могут хранить файлы в различных облачных сервисах

Если вы хотите следить за сериалом, пожалуйста, не стесняйтесь подписаться на мою новостную рассылку, где я объявляю весь свой новый контент. Если у вас есть другие вопросы, вы можете связаться со мной в Интернете в Твиттере, где я нахожусь @mblayman Анкет

Поймите Джанго (16 серии деталей)

Оригинал: “https://dev.to/mblayman/understand-django-making-sense-of-settings-f6m”