Отправка письма из Django через SMTP: пошаговый гайд
К концу вы отправите первое письмо из Django-приложения через реальный SMTP-сервер и увидите его в почтовом ящике. Разберём настройки, отправку из shell и проверку без спама.

За полчаса вы настроите Django на отправку писем через SMTP и получите первое письмо в свой ящик — сначала из консоли, потом из кода. Проверено на Django 5.x, работает и на 4.2 LTS. Всё, что понадобится дополнительно, — почтовый ящик, у которого включён SMTP-доступ, и пароль приложения для него.
Что нужно иметь до начала
- установленный Python 3.10+ и созданный проект Django (команда
django-admin startprojectуже отработала,manage.py runserverзапускается без ошибок); - почтовый ящик с доступом по SMTP. У Gmail, Яндекса и Mail.ru обычный пароль от ящика не подойдёт — нужен пароль приложения*, который выдаётся отдельно в настройках безопасности;
- адрес SMTP-сервера, порт и способ шифрования вашего провайдера. Для Яндекса это
smtp.yandex.ru, порт 465, SSL. Для Gmail —smtp.gmail.com, порт 587, TLS. Точные значения смотрите в справке своего почтового сервиса.
Django ничего не отправляет сам по себе — он подключается к чужому SMTP-серверу и просит его доставить письмо. Поэтому половина работы — это правильные реквизиты подключения.
* Пароль приложения — отдельный пароль, который почтовый сервис генерирует для сторонних программ. Основной пароль от ящика при этом не раскрывается, и такой пароль можно отозвать, не меняя главный.
Шаг 1. Пропишите настройки SMTP
Откройте settings.py и добавьте блок настроек почты. Значения ниже — пример для Яндекса на порту 465 (SSL). Под свой провайдер поменяйте хост, порт и флаг шифрования.
# settings.py — пример для Яндекс.Почты, Django 5.x
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.yandex.ru"
EMAIL_PORT = 465
EMAIL_USE_SSL = True # для порта 465
EMAIL_USE_TLS = False # TLS и SSL одновременно не включают
EMAIL_HOST_USER = "you@yandex.ru"
EMAIL_HOST_PASSWORD = "YOUR_APP_PASSWORD" # пароль приложения, не пароль от ящика
DEFAULT_FROM_EMAIL = "you@yandex.ru" # адрес в поле "От кого"
Для Gmail строки шифрования выглядят иначе: порт 587, EMAIL_USE_TLS = True, а EMAIL_USE_SSL — False. Порт 465 идёт с SSL, порт 587 — с TLS; не включайте оба флага сразу.
Проверка: файл сохраняется, manage.py runserver по-прежнему стартует без ошибок импорта. Ошибки на этом шаге быть не должно — реальное подключение произойдёт только при отправке.
Шаг 2. Уберите пароль из кода
Класть EMAIL_HOST_PASSWORD прямо в settings.py нельзя: файл почти всегда попадает в git, и пароль уедет в репозиторий. Вынесите секреты в переменные окружения.
# settings.py
import os
EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER", "")
EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD", "")
Перед запуском задайте переменные в текущей сессии терминала (Linux/macOS):
export EMAIL_HOST_USER="you@yandex.ru"
export EMAIL_HOST_PASSWORD="YOUR_APP_PASSWORD"
В Windows PowerShell — $env:EMAIL_HOST_USER="you@yandex.ru". Для постоянного хранения удобнее файл .env и пакет вроде python-dotenv, но для первого письма хватит и export.
Проверка: выполните python -c "import os; print(os.environ.get('EMAIL_HOST_USER'))" в том же терминале — должен вывестись ваш адрес, а не пустая строка.
Шаг 3. Отправьте первое письмо из shell
Не пишите сразу вьюху — сначала проверьте связку в интерактивной консоли. Запустите python manage.py shell и введите:
from django.core.mail import send_mail
send_mail(
subject="Тест из Django",
message="Если вы это читаете, SMTP настроен верно.",
from_email=None, # None подставит DEFAULT_FROM_EMAIL
recipient_list=["your_inbox@example.com"],
fail_silently=False, # чтобы увидеть реальную ошибку, а не тишину
)
Функция send_mail вернёт число доставленных сообщений. fail_silently=False критично на этапе отладки: с True Django молча проглотит любую ошибку, и вы будете гадать, почему письма нет.
Проверка: в консоли появилась строка 1, а в вашем ящике (проверьте и папку «Спам») — письмо с темой «Тест из Django». Если так — самое сложное позади.
Шаг 4. Вынесите отправку в код приложения
Теперь то же самое из вьюхи. Для писем с HTML-версией и вложениями удобнее EmailMessage или EmailMultiAlternatives, но для простого текстового письма достаточно send_mail.
# views.py
from django.core.mail import send_mail
from django.http import HttpResponse
def notify(request):
send_mail(
subject="Заявка принята",
message="Спасибо, мы получили вашу заявку.",
from_email=None,
recipient_list=["client@example.com"],
fail_silently=False,
)
return HttpResponse("Письмо отправлено")
Пропишите маршрут в urls.py, откройте адрес в браузере.
Проверка: в браузере открывается страница с текстом «Письмо отправлено», в ящике получателя — новое письмо.
Как отлаживать, не спамя реальные ящики
Пока вы правите шаблоны письма, отправлять каждое тестовое сообщение на живой SMTP не нужно. Django умеет писать письма в консоль или в файл — реквизиты сервера при этом не требуются вообще.
| EMAIL_BACKEND | Что делает | Когда использовать |
|---|---|---|
...backends.smtp.EmailBackend | реально отправляет через SMTP | прод и финальная проверка |
...backends.console.EmailBackend | печатает письмо в терминал runserver | отладка текста и шаблонов |
...backends.filebased.EmailBackend | складывает письма в файлы | сохранить историю отправок локально |
...backends.locmem.EmailBackend | держит письма в памяти | тесты (django.core.mail.outbox) |
Для консольного бэкенда задайте EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend", filebased требует ещё EMAIL_FILE_PATH. Точные пути бэкендов сверяйте в разделе про отправку почты в документации Django вашей версии.
Отлаживайте текст письма на консольном бэкенде, а SMTP включайте только для финальной проверки. Так вы не разошлёте два десятка «тест-тест-тест» на боевую почту клиента и не попадёте в спам-фильтры за частые одинаковые письма.
Если не получилось
Пять ошибок, которые видят чаще всего:
- SMTPAuthenticationError — сервер отклонил логин или пароль. Почти всегда вы подставили основной пароль от ящика вместо пароля приложения. Сгенерируйте пароль приложения в настройках безопасности почты и используйте его.
- Connection unexpectedly closed или зависание — рассогласование порта и шифрования. Порт 465 требует
EMAIL_USE_SSL = True, порт 587 —EMAIL_USE_TLS = True. Оба флага одновременно не включают. - send_mail вернул 0, ошибки нет — у вас
fail_silently=True. ПоставьтеFalseи посмотрите настоящую причину. - Письмо ушло, но не пришло — проверьте папку «Спам». Часто сервисы режут письма, у которых поле «От кого» не совпадает с
EMAIL_HOST_USER. ДержитеDEFAULT_FROM_EMAILи логин на одном домене. - [Errno 111] Connection refused — до SMTP-порта нет доступа. На части хостингов исходящие соединения на 25/465/587 закрыты; уточните у поддержки хостинга, открыт ли нужный порт.
Что дальше
Первое письмо отправлено — дальше стоит настроить три вещи. Первое: выносите отправку из вьюхи в фоновую задачу (Celery или встроенные средства очередей), потому что синхронный вызов SMTP тормозит ответ пользователю на секунды и роняет запрос, если почтовый сервер недоступен. Второе: для писем с вёрсткой переходите на EmailMultiAlternatives и шаблоны через render_to_string. Третье: в тестах используйте locmem-бэкенд и проверяйте django.core.mail.outbox — доставку писем в тестах не гоняют через реальный SMTP. Доставляемость и защита от попадания в спам (SPF, DKIM) — отдельная большая тема на стороне почтового домена, здесь мы её не разбирали.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Django documentation — Sending email
Частые вопросы
У меня Django 4.2, а не 5.x — команды те же?
Письмо не приходит, но ошибок в консоли нет. Что не так?
Обязательно ли выносить пароль в переменные окружения?
Почему не подходит обычный пароль от Gmail или Яндекса?
На хостинге письма не отправляются, хотя локально всё работало.
Стоит ли отправлять письма прямо из вьюхи в проде?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.