Настройка отправки писем email в Django для mail, яндекс, gmail
23 сентября 2015 г. 0:49
В зависимости от того, какой SMPT сервер хотим использовать для отправки писем с сайта, нужно указывать соответствующий хост и порт этого сервера. В Django нужно прописать настройки в settings.py
:
Имейте ввиду, что большинство почтовых служ требуют в качестве пароля в параметре EMAIL_HOST_PASSWORD
не пароль от аккаунта, а специально сгенерированный пароль приложения.
mail.ru
EMAIL_HOST = 'smtp.mail.ru' EMAIL_PORT = 2525 EMAIL_HOST_USER = "your@mail.ru" EMAIL_HOST_PASSWORD = "password" EMAIL_USE_TLS = True EMAIL_USE_SSL = False
Инструкция по генерации пароля приложения: https://help.mail.ru/mail/security/protection/external
gmail.com
EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 587 EMAIL_HOST_USER = "your@gmail.com" EMAIL_HOST_PASSWORD = "password" EMAIL_USE_TLS = True EMAIL_USE_SSL = False
Инструкция по генерации пароля приложения: Google блокирует попытку авторизации с моего сайта или как разрешить доступ Google авторизации из другого места удаленно?
yandex.ru
EMAIL_HOST = 'smtp.yandex.ru' EMAIL_PORT = 465 EMAIL_HOST_USER = "your@yandex.ru" EMAIL_HOST_PASSWORD = "password" EMAIL_USE_TLS = False EMAIL_USE_SSL = True
При использовании другой службы электронной почты посмотрите, какой хост и порт у этой службы. Например, для Google почты данная информация находится здесь: support.google.com/a/answer/176600?hl=ru#zippy=%2Cкак-использовать-smpt-сервер-gmail
Внимание: для получения писем об ошибках сайта для Яндекс и mail (и других почтовых служб) обязательно нужно указывать SERVER_EMAIL
такой же адрес электронной почты, какой указывается в EMAIL_HOST_USER
. Если не будет совпадать, то письма не будут посылаться! Поэтому вне зависимости от используемой службы добавьте ещё две следующие строчки в settings.py
для отправки сообщений:
SERVER_EMAIL = EMAIL_HOST_USER DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
Отправить сообщение в Django
Чтобы послать письмо, нужно лишь в коде где-нибудь, например, во views.py
вызвать команду send_mail
:
from django.conf import settings from django.core.mail import send_mail send_mail('Тема', 'Тело письма', settings.EMAIL_HOST_USER, ['to@example.com'])
Обратите внимание, что для предотвращения ошибки 501 sender address must match authenticated user
нужно использовать адрес отправителя такой же, как EMAIL_HOST_USER
(адрес пользователя при подключении к SMPT серверу). Более подробно об этой ошибки в статье: Error: SMTPRecipientsRefused 501 - sender address must match authenticated user
Если вы хотите добавить имя отправителя (или какое-либо название), то используйте headers
:
headers = {'To': '{} <{}>'.format(user.get_full_name(), 'to@example.com')} send_mail('Тема', 'Тело письма' , settings.EMAIL_HOST_USER, ['to@example.com'], headers=headers)
Обратите внимание, что в headers электронная почта получателя (в коде: to@example.com
) должна совпадать.
Если вы хотите использовать html-теги в теле письма, то удобно создать отдельный файл и использовать render_to_string()
:
from django.conf import settings from django.core.mail import send_mail from django.template.loader import render_to_string msg = render_to_string('path/to/template.html', {'test_variable': 'xxx'}) send_mail('Тема', msg, settings.EMAIL_HOST_USER, ['to@example.com'], html_message=msg)
Расширенный пример использования send_mail с помощью post_office
Приведу простой пример, но с более гибкими возможностями отправки писем с сайта. Предложенный в этом разделе код отправляет письма:
- нескольким эл. почтам,
- с вложением,
- через некоторый временной интервал (это нужно, чтобы, например, сразу 100 писем не посылались с сайта, так как у некоторых почтовых служб есть ограничение в максимальной отправке писем в минуту).
Для начала поставим пакет post_office:
$ pip install django-post-office
В settings.py
добавьте:
INSTALLED_APPS = ( ... 'post_office', ) EMAIL_BACKEND = 'post_office.EmailBackend'
Теперь добавьте код, например, во views.py
примерно такой:
emails = ['email_1@gmail.com', 'email_2@gmail.com', 'email_3@gmail.com'] me = 'Название компании <{}>'.format(settings.EMAIL_HOST_USER) subject = 'Тестовое письмо' attachments = { 'Тестовое вложение.pdf': join(settings.MEDIA_ROOT, 'test_attachment.pdf') } now = timezone.now() delta_sec = -70 # Нужно, чтобы первое письмо было отправлено сразу же for email in emails: delta_sec += random.randint(60, 70) scheduled_time = now + timedelta(seconds=delta_sec) message = render_to_string('my_app/email.html', {'email': email, 'some_var': 'xxx'}) headers = {'To': 'Получатель письма от компании <{}>'.format(email)} send(email, me, subject=subject, message=message, html_message=message, scheduled_time=scheduled_time, headers=headers, attachments=attachments)
Список emails
может формироваться разным способом. Такой список может быть получает с базы данных, например, с некоторой модели MyModel: MyModel.objects.all()
. Или может быть с формы поля CharField
или Textarea
.
В delta_sec += random.randint(60, 70)
определяем через какое время посылать следующее письмо. Я использую рандомное число от 60 до 70 секунд, чтобы не через ровно одинаковый интервал посылались письма, а чуть более произвольный в рамках 65 +-5 секунд. Это число я беру с запасом, чтобы в уменьшить вероятность попадания письма в спам, вы можете уменьшить данное значение.
Данным кодом я довольно часто пользуюсь, когда нужно отправить письмо несколько людям.
У post-office метод send
сам не отправляет сразу письмо получателю, а только создаёт его в базе данных.
Это полезно не только для возможности отправлять письма в определённое время, но и чтобы отправка письма не занимала много времени: проще сохранить письмо в базе данных, а затем его отправить (например, через cron), чем, находясь на сайте и кликнув на кнопку "Отправить" ждать пока отправятся письма. Отправка письма - всегда долгое по времени задача. Это особенно актуально, когда посетители отправляют форму с сайта.
Чтобы отправить письма, нужно в cron добавить команду send_queued_mail
. В linux для этого вызываем редактор cron:
$ crontab -e
а затем добавляем вызов команды send_queued_mail, прописывая путь до manage.py вашего проекта:
*/2 * * * * python /project/path/to/manage.py send_queued_mail
Эта команда каждые две минуты проверяет, есть ли в базе данных письма в очереди на отправку. Если есть то, отправляет.
Решение ошибок при отправке почты
Зачастую ошибки происходят не в написанном коде, а в том, что письма не доходят до получателя. Например, в google можно получить следующую ошибку:
SMTP error code 535 Username and Password not accepted. Learn more at https://support.google.com/mail/?p=BadCredentials
Посмотрите статью, как решить данную проблему подключения к гугл почте: Google блокирует попытку авторизации с моего сайта или как разрешить доступ Google авторизации из другого места удаленно?
Если вы подключаетесь через другую почтовую службу, то поищите соответствующую информацию.
Дополнительный материал
- Как отправить письмо с сайта с разных почт Django
- Google блокирует попытку авторизации с моего сайта или как разрешить доступ Google авторизации из другого места удаленно?
- Описание отправки почты на официальном сайте Django: https://docs.djangoproject.com/en/3.1/topics/email/
Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.
Книга предназначается для широкого круга читателей и, по мнению автора, будет полезна специалистам отдела закупок и логистики, категорийным и финансовым менеджерам, менеджерам по продажам, аналитикам, руководителям и директорам, в компетенции которых принятие решений по управлению ассортиментом.
Комментарии: 26
13.09.2018 10:18 #
Подскажите, как сделать так чтоб настройки EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USE R и т.д. указывать в админке и при этом все работало?
Ответить
12.02.2021 2:19 #
Антон, добрый день!
Посмотрите мою статью https://vivazzi.pro/it/send-email-from-different-account-django/
В ней я расписал, как это можно сделать.
Ответить
15.09.2018 3:50 #
Антон, посмотрите, как сделано в файле: /django/core/mail/backends/smtp.py
А именно вот эти строки:
И определить свой Бекэнд (можно как пример посмотреть у приложения post_office как сделано: /post_office/backends.py) как-то так:
В settings.py добавить
EMAIL_BACKEND = 'my_app.EmailBackend'
Примерно так. Сам я ни разу не задавался такой задачей. Попробуйте, вышеприведённый код тоже не тестировал, но по идее должно работать. Оно будет работать если при отправки письма каждый раз инициализируется бекэнд, если же он только один раз при запуске проекта, то тут конечно думать надо уже конкретно код писать.
И в гугле сходу я не нашёл. Только вот https://stackoverflow.com/questions/15187697/django-sending-email-with-dynamic-smtp-settings/15187806 - но там просто отсылка на документацию на создание своего бекэнда без конкретного кода.
Ответить
24.01.2019 19:07 #
Подскажите пожалуйста как кастомизировать вид самого письма отправленого на почту
Ответить
25.01.2019 13:36 #
Зеновый, здравствуйте!
Например, так:
А файл
path\to\template.html
может содержать теги.Ответить
19.04.2019 14:39 #
Здравствуйте!
А в качестве settings.EMAIL_HOST_USER я могу указать любую строку ? я хочу чтобы в письме отображался отправитель в качестве любого слова а не заданного email
Ответить
21.04.2019 6:23 #
Артём, здравствуйте!
При использовании метода
send_mail('Тема', msg , settings.EMAIL_HOST_USER, ['to@example.com'])
вам нужно использовать settings.EMAIL_HOST_USER. Но чтобы добавить имя отправителю нужно сделать так:Ответить
19.07.2019 11:52 #
from django.conf import setting s send_mail('Тема', 'Тело письма', settings.EMAIL_HOST_USER, ['to@example.com'] ) Подскажите куда это вписывать?
Ответить
19.07.2019 23:34 #
Да можно в любом месте писать, где нужно его выполнить. Допустим, во view.py в методе, который выполняется, когда пользователь переходит по url
Ответить
21.08.2019 17:02 #
kak v django reset password
Ответить
24.08.2019 0:49 #
Посмотрите эту ссылку: https://simpleisbetterthancomplex.com/tutorial/2016/09/19/how-to-create-password-reset-view.html
Ответить
27.08.2019 18:46 #
А что можно сделать, чтобы сообщения не банили из-за подозрения на спам? Использую рассылку от yandex
Ответить
28.08.2019 2:57 #
Общие рекомендации:
то есть нужно проверить текст на спам-слова.
Точных инструкций я, если честно, не знаю.
А лучше, как многие советуют, использовать сторонний сервис рассылок - там должно быть настроено, чтобы письма в спам не попадали, но не факт, конечно.
Ответить
12.09.2019 18:50 #
Отлично ! при EMAIL_USE_TLS = True через Яндекс не уходило. Исправил на SSL теперь все работает . Спасибо!
Ответить
14.09.2019 10:06 #
Рад, что статья оказалась для вас полезной!
Ответить
07.05.2021 14:15 #
Спасибо, тебе, добрый человек) ! Все расписал как надо.
Ответить
10.05.2021 5:36 #
Рад стараться :)
Ответить
18.06.2022 8:30 #
Спасибо тебе, друг!
Ответить
17.07.2022 17:01 #
Пожалуйста!)) рад, что статья была полезной! :)
Ответить
13.07.2022 12:03 #
Здравствуйте!
У меня есть блог сайт и я должен рассылать письма в случае если автору поста пишут комментарий. Подскажите пожалуйста как я могу это сделать?
Ответить
13.07.2022 12:05 #
сайт загружен на heroku и подключен к send grid*
Ответить
17.07.2022 16:58 #
Добрый день! Я с хероку не работал ни разу... но в доках к хероку есть инструкции. Что именно не получается?
Ответить
19.08.2023 20:30 #
Привет, как добавить кнопку "Разослать" в админку Django и привязать ее к этому view из статьи?
Ответить
02.04.2024 15:04 #
И как ты собрался не из под venv стучаться в manage.py, умник?
Ответить
02.04.2024 15:10 #
Это я же . Для всех адекватных, в крон надо пихать вот так: source path/to/activate && path/to/manage.py send_queued_mail
Ответить
02.04.2024 15:30 #
Дополню, пожалуй, что автор не написал кучу импортов : import rando m from datetime import timedelt a from django.utils import timezone
Ответить