Отправка электронной почты
Хотя Python предоставляет интерфейс для отправки почты через модуль smtplib, Django предлагает несколько лёгких оболочек над ним. Эти оболочки созданы для того, чтобы упростить отправку электронной почты, помочь тестировать отправку писем во время разработки и обеспечить поддержку платформ, которые не могут использовать SMTP.
Код находится в модуле django.core.mail.
Краткие примеры
Для простой отправки электронной почты используйте send_mail(). Например, чтобы отправить обычное текстовое сообщение:
from django.core.mail import send_mail
send_mail(
"Subject here",
"Here is the message.",
"from@example.com",
["to@example.com"],
fail_silently=False,
)
Если нужны дополнительные возможности отправки электронной почты, используйте EmailMessage или EmailMultiAlternatives. Например, чтобы отправить составное письмо с версиями в формате HTML и обычного текста, используя определённый шаблон и пользовательские заголовки, можно применить следующий подход:
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
# First, render the plain text content.
text_content = render_to_string(
"templates/emails/my_email.txt",
context={"my_variable": 42},
)
# Secondly, render the HTML content.
html_content = render_to_string(
"templates/emails/my_email.html",
context={"my_variable": 42},
)
# Then, create a multipart email instance.
msg = EmailMultiAlternatives(
subject="Subject here",
body=text_content,
from_email="from@example.com",
to=["to@example.com"],
headers={"List-Unsubscribe": "<mailto:unsub@example.com>"},
)
# Lastly, attach the HTML content to the email instance and send.
msg.attach_alternative(html_content, "text/html")
msg.send()
Почта отправляется с использованием SMTP-хоста и порта, указанных в настройках EMAIL_HOST и EMAIL_PORT. Настройки EMAIL_HOST_USER и EMAIL_HOST_PASSWORD, если они заданы, используются для аутентификации на SMTP-сервере, а настройки EMAIL_USE_TLS и EMAIL_USE_SSL определяют, будет ли использоваться защищённое соединение.
Примечание
Кодировка электронной почты, отправляемой с помощью django.core.mail, будет соответствовать значению настройки DEFAULT_CHARSET.
send_mail()
-
send_mail(subject, message, from_email, recipient_list, *, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)[исходный код]
В большинстве случаев электронную почту можно отправить с помощью django.core.mail.send_mail().
Параметры subject, message, from_email и recipient_list являются обязательными.
-
subject: строка. -
message: строка. -
from_email: строка. ЕслиNone, Django использует значение настройкиDEFAULT_FROM_EMAIL. -
recipient_list: список строк, каждая из которых является адресом электронной почты. Каждый получатель изrecipient_listувидит остальных получателей в поле «Кому:» письма.
Следующие параметры необязательны; если они используются, их нужно передавать как именованные аргументы.
-
fail_silently: логическое значение. Если оно равноFalse,send_mail()вызовет исключениеsmtplib.SMTPExceptionпри возникновении ошибки. Список возможных исключений приведён в документацииsmtplib; все они являются подклассамиSMTPException. -
auth_user: необязательное имя пользователя для аутентификации на SMTP-сервере. Если оно не указано, Django использует значение настройкиEMAIL_HOST_USER. -
auth_password: необязательный пароль для аутентификации на SMTP-сервере. Если он не указан, Django использует значение настройкиEMAIL_HOST_PASSWORD. -
connection: необязательный бэкенд электронной почты для отправки письма. Если он не указан, будет использоваться экземпляр бэкенда по умолчанию. Подробнее см. в документации о бэкендах электронной почты. -
html_message: если заданhtml_message, результатом будет письмо типа multipart/alternative, в которомmessageимеет тип содержимого text/plain, аhtml_message— тип содержимого text/html.
Возвращаемое значение — количество успешно доставленных сообщений (оно может быть 0 или 1, поскольку функция отправляет только одно сообщение).
Устарело с версии 6.0: Передача fail_silently и последующих параметров как позиционных аргументов устарела.
send_mass_mail()
-
send_mass_mail(datatuple, *, fail_silently=False, auth_user=None, auth_password=None, connection=None)[исходный код]
django.core.mail.send_mass_mail() предназначена для массовой рассылки электронной почты.
datatuple — это кортеж, каждый элемент которого имеет следующий формат:
(subject, message, from_email, recipient_list)
fail_silently, auth_user, auth_password и connection выполняют те же функции, что и в send_mail(). Если они используются, их нужно передавать как именованные аргументы.
Каждый отдельный элемент datatuple соответствует отдельному письму. Как и в send_mail(), все получатели из одного и того же recipient_list увидят остальные адреса в поле «Кому:» письма.
Например, следующий код отправит два разных сообщения двум разным группам получателей, но соединение с почтовым сервером будет установлено только одно:
message1 = (
"Subject here",
"Here is the message",
"from@example.com",
["first@example.com", "other@example.com"],
)
message2 = (
"Another Subject",
"Here is another message",
"from@example.com",
["second@test.com"],
)
send_mass_mail((message1, message2), fail_silently=False)
Возвращаемое значение — количество успешно доставленных сообщений.
Устарело с версии 6.0: Передача fail_silently и последующих параметров как позиционных аргументов устарела.
send_mass_mail() и send_mail()
Основное различие между send_mass_mail() и send_mail() заключается в том, что send_mail() при каждом вызове устанавливает соединение с почтовым сервером, тогда как send_mass_mail() использует одно соединение для всех сообщений. Поэтому send_mass_mail() немного эффективнее.
mail_admins()
-
mail_admins(subject, message, *, fail_silently=False, connection=None, html_message=None)[исходный код]
django.core.mail.mail_admins() — это сокращённый способ отправить письмо администраторам сайта, указанным в настройке ADMINS.
mail_admins() добавляет в начало темы значение настройки EMAIL_SUBJECT_PREFIX, которое по умолчанию равно "[Django] ".
В заголовке «От:» письма будет указано значение настройки SERVER_EMAIL.
Этот метод существует для удобства и повышения читаемости кода.
Если задан html_message, результатом будет письмо типа multipart/alternative, в котором message имеет тип содержимого text/plain, а html_message — тип содержимого text/html.
Устарело с версии 6.0: Передача fail_silently и последующих параметров как позиционных аргументов устарела.
mail_managers()
-
mail_managers(subject, message, *, fail_silently=False, connection=None, html_message=None)[исходный код]
django.core.mail.mail_managers() работает так же, как mail_admins(), но отправляет письмо менеджерам сайта, указанным в настройке MANAGERS.
Устарело с версии 6.0: Передача fail_silently и последующих параметров как позиционных аргументов устарела.
Примеры
Этот код отправляет одно письмо адресатам john@example.com и jane@example.com; оба адреса будут указаны в поле «Кому:»:
send_mail(
"Subject",
"Message.",
"from@example.com",
["john@example.com", "jane@example.com"],
)
Этот код отправляет сообщение адресатам john@example.com и jane@example.com, причём каждый из них получает отдельное письмо:
datatuple = (
("Subject", "Message.", "from@example.com", ["john@example.com"]),
("Subject", "Message.", "from@example.com", ["jane@example.com"]),
)
send_mass_mail(datatuple)
Защита от внедрения заголовков
Внедрение заголовков — это уязвимость, при которой злоумышленник добавляет дополнительные заголовки электронной почты, чтобы управлять полями «Кому:» и «От:» в письмах, создаваемых вашими скриптами.
Все описанные выше функции Django для работы с электронной почтой защищают от внедрения заголовков, запрещая символы перевода строки в значениях заголовков. Если в subject, from_email или recipient_list содержится символ перевода строки (в стиле Unix, Windows или Mac), функция отправки почты (например, send_mail()) вызовет исключение ValueError и, следовательно, не отправит письмо. Вы несёте ответственность за проверку всех данных перед передачей их функциям отправки почты.
Если message содержит заголовки в начале строки, эти заголовки будут выведены в самом начале сообщения электронной почты.
Ниже приведён пример представления, которое получает subject, message и from_email из данных POST-запроса, отправляет их в admin@example.com и по завершении перенаправляет пользователя на «/contact/thanks/»:
from django.core.mail import send_mail
from django.http import HttpResponse, HttpResponseRedirect
def send_email(request):
subject = request.POST.get("subject", "")
message = request.POST.get("message", "")
from_email = request.POST.get("from_email", "")
if subject and message and from_email:
try:
send_mail(subject, message, from_email, ["admin@example.com"])
except ValueError:
return HttpResponse("Invalid header found.")
return HttpResponseRedirect("/contact/thanks/")
else:
# In reality we'd use a form class
# to get proper validation errors.
return HttpResponse("Make sure all fields are entered and valid.")
В предыдущих версиях для некоторых недопустимых заголовков вызывалось исключение django.core.mail.BadHeaderError. Теперь вместо него используется ValueError.
Класс EmailMessage
Функции Django send_mail() и send_mass_mail() на самом деле являются тонкими обёртками, использующими класс EmailMessage.
Через send_mail() и связанные функции-обёртки доступны не все возможности класса EmailMessage. Чтобы использовать расширенные возможности, такие как получатели скрытой копии, файловые вложения или составные письма, необходимо создавать экземпляры EmailMessage напрямую.
Примечание
Это особенность проектирования. Изначально send_mail() и связанные функции были единственным интерфейсом, предоставляемым Django. Однако со временем список принимаемых ими параметров постепенно увеличивался. Было разумно перейти к более объектно-ориентированному проектированию сообщений электронной почты и сохранить исходные функции только для обратной совместимости.
Класс EmailMessage отвечает за создание самого сообщения электронной почты. Затем за отправку письма отвечает бэкенд электронной почты.
Для удобства класс EmailMessage предоставляет метод send() для отправки одного письма. Если нужно отправить несколько сообщений, API бэкенда электронной почты предоставляет альтернативный вариант.
Объекты EmailMessage
-
class EmailMessage[исходный код] -
Класс
EmailMessageинициализируется следующими параметрами. Все параметры необязательны, и их можно задать в любой момент до вызова методаsend().Первые четыре параметра можно передавать как позиционные аргументы или аргументы-ключевые слова, но при использовании позиционных аргументов их необходимо указывать в заданном порядке:
-
subject: Тема письма. -
body: Текст сообщения. Это должно быть сообщение в обычном текстовом формате. -
from_email: Адрес отправителя. Допустимы оба формата:fred@example.comи"Fred" <fred@example.com>. Если параметр не указан, используется настройкаDEFAULT_FROM_EMAIL. -
to: Список или кортеж адресов получателей.
Следующие параметры, если они используются, необходимо передавать как аргументы-ключевые слова:
-
cc: Список или кортеж адресов получателей, используемых в заголовке «Cc» при отправке письма. -
bcc: Список или кортеж адресов, используемых в заголовке «Bcc» при отправке письма. -
reply_to: Список или кортеж адресов получателей, используемых в заголовке «Reply-To» при отправке письма. -
attachments: Список вложений для добавления к сообщению. Каждый элемент может быть экземпляромMIMEPartилиEmailAttachment, либо кортежем с атрибутами(filename, content, mimetype).Изменено в Django 5.2:Добавлена поддержка элементов
EmailAttachmentтипаattachments.Изменено в Django 6.0:Добавлена поддержка объектов
MIMEPartв спискеattachments. -
headers: Словарь дополнительных заголовков для добавления к сообщению. Ключи — это имена заголовков, значения — значения заголовков. Вызывающий код должен обеспечить соответствие имён и значений заголовков правильному формату для сообщения электронной почты. Соответствующий атрибут —extra_headers. -
connection: Экземпляр бэкенда электронной почты. Используйте этот параметр, если отправляетеEmailMessageс помощьюsend()и хотите использовать одно и то же соединение для нескольких сообщений. Если параметр не указан, при вызовеsend()создаётся новое соединение. При использовании send_messages() этот параметр игнорируется.
Устарело начиная с версии 6.0: Передача всех параметров, кроме первых четырёх, в качестве позиционных аргументов устарела.
Например:
from django.core.mail import EmailMessage email = EmailMessage( subject="Hello", body="Body goes here", from_email="from@example.com", to=["to1@example.com", "to2@example.com"], bcc=["bcc@example.com"], reply_to=["another@example.com"], headers={"Message-ID": "foo"}, )Класс содержит следующие методы:
-
send(fail_silently=False)[исходный код] -
Отправляет сообщение. Если при создании письма было указано соединение, будет использоваться это соединение. В противном случае будет создан и использован экземпляр бэкенда по умолчанию. Если аргумент-ключевое слово
fail_silentlyимеет значениеTrue, исключения, возникающие при отправке сообщения, будут подавлены. Пустой список получателей не вызовет исключения. Метод вернёт1, если сообщение было успешно отправлено, и0в противном случае.
-
message(policy=email.policy.default)[исходный код] -
Создаёт и возвращает объект Python
email.message.EmailMessage, представляющий отправляемое сообщение.Аргумент-ключевое слово
policyпозволяет указать набор правил для обновления и сериализации представления сообщения. Он должен быть объектомemail.policy.Policy. По умолчанию используетсяemail.policy.default. В некоторых случаях может потребоваться использоватьSMTP,SMTPUTF8или пользовательскую политику. Например,django.core.mail.backends.smtp.EmailBackendиспользует политикуSMTP, чтобы обеспечить окончания строк\r\n, требуемые протоколом SMTP.Если вам когда-либо понадобится расширить класс Django
EmailMessage, вероятно, потребуется переопределить этот метод, чтобы поместить нужное содержимое в объект Python EmailMessage.Изменено в Django 6.0:Добавлен аргумент-ключевое слово
policy, а возвращаемый тип изменён на экземплярEmailMessage.
-
recipients()[исходный код] -
Возвращает список всех получателей сообщения, независимо от того, указаны ли они в атрибутах
to,ccилиbcc. Возможно, этот метод также потребуется переопределить при создании подкласса, поскольку SMTP-серверу необходимо сообщить полный список получателей при отправке сообщения. Если в вашем классе предусмотрен другой способ указания получателей, их также необходимо возвращать из этого метода.
-
attach(filename, content, mimetype)[исходный код] - attach(mimepart)
-
Создаёт новое вложение и добавляет его к сообщению. Вызвать
attach()можно двумя способами:-
Можно передать три аргумента:
filename,contentиmimetype.filename— это имя файла вложения, которое будет отображаться в письме,content— данные, содержащиеся во вложении, аmimetype— необязательный MIME-тип вложения. Если не указатьmimetype, тип MIME-содержимого будет определён по имени файла вложения.Например:
message.attach("design.png", img_data, "image/png")Если указать
mimetypeсо значением message/rfc822,contentможет быть объектомdjango.core.mail.EmailMessage, Pythonemail.message.EmailMessageилиemail.message.Message.Для
mimetype, начинающегося с text/, содержимое должно быть строкой. Двоичные данные будут декодированы с использованием UTF-8; если это не удастся, MIME-тип изменится на application/octet-stream, а данные будут прикреплены без изменений. -
Для вложений, требующих дополнительных заголовков или параметров, можно передать методу
attach()один объект PythonMIMEPart. Он будет напрямую добавлен к итоговому сообщению. Например, чтобы добавить встроенное изображение с Content-ID:cid = email.utils.make_msgid() inline_image = email.message.MIMEPart() inline_image.set_content( image_data_bytes, maintype="image", subtype="png", disposition="inline", cid=f"<{cid}>", ) message.attach(inline_image) message.attach_alternative(f'… <img src="cid:${cid}"> …', "text/html")В документации Python для
email.contentmanager.set_content()описаны поддерживаемые аргументыMIMEPart.set_content().Изменено в Django 6.0:Добавлена поддержка вложений
MIMEPart.Устарело начиная с версии 6.0: Поддержка вложений
email.mime.base.MIMEBaseустарела. Вместо них используйтеMIMEPart.
-
-
attach_file(path, mimetype=None)[исходный код] -
Создаёт новое вложение из файла в файловой системе. Передайте путь к файлу для вложения и, при необходимости, MIME-тип, который следует использовать для вложения. Если MIME-тип не указан, он будет определён по имени файла. Использовать метод можно так:
message.attach_file("/images/weather_map.png")Для MIME-типов, начинающихся с text/, двоичные данные обрабатываются так же, как в
attach().
-
-
class EmailAttachment -
Добавлено в Django 5.2.
Именованный кортеж для хранения вложений письма.
Именованный кортеж имеет следующие индексы:
filenamecontentmimetype
Отправка содержимого в альтернативных форматах
Отправка нескольких версий содержимого
Иногда полезно включить в письмо несколько версий содержимого; классический пример — отправка текстовой и HTML-версий сообщения. С помощью библиотеки электронной почты Django это можно сделать, используя класс EmailMultiAlternatives.
-
class EmailMultiAlternatives[исходный код] -
Подкласс
EmailMessage, который позволяет добавлять к письму дополнительные версии тела сообщения с помощью методаattach_alternative(). Он напрямую наследует все методы (включая инициализацию класса) отEmailMessage.-
alternatives -
Список именованных кортежей
EmailAlternative. Это особенно полезно в тестах:self.assertEqual(len(msg.alternatives), 1) self.assertEqual(msg.alternatives[0].content, html_content) self.assertEqual(msg.alternatives[0].mimetype, "text/html")
Альтернативные версии следует добавлять только с помощью метода
attach_alternative()или передавать конструктору.Изменено в Django 5.2:В более ранних версиях
alternativesпредставлял собой список обычных кортежей, а не именованных кортежейEmailAlternative.
-
attach_alternative(content, mimetype)[исходный код] -
Добавляет к письму альтернативное представление тела сообщения.
Например, чтобы отправить текстовую и HTML-версии, можно написать:
from django.core.mail import EmailMultiAlternatives subject = "hello" from_email = "from@example.com" to = "to@example.com" text_content = "This is an important message." html_content = "<p>This is an <strong>important</strong> message.</p>" msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") msg.send()
-
body_contains(text)[исходный код] -
Добавлено в Django 5.2.
Возвращает логическое значение, указывающее, содержится ли заданное
textвbodyписьма и во всех прикреплённых альтернативах типа MIMEtext/*.Это может быть полезно при тестировании писем. Например:
def test_contains_email_content(self): subject = "Hello World" from_email = "from@example.com" to = "to@example.com" msg = EmailMultiAlternatives(subject, "I am content.", from_email, [to]) msg.attach_alternative("<p>I am content.</p>", "text/html") self.assertIs(msg.body_contains("I am content"), True) self.assertIs(msg.body_contains("<p>I am content.</p>"), False)
-
-
class EmailAlternative -
Добавлено в Django 5.2.
Именованный кортеж для хранения альтернативных версий содержимого письма.
Именованный кортеж имеет следующие индексы:
contentmimetype
Изменение типа содержимого по умолчанию
По умолчанию MIME-тип параметра body в объекте EmailMessage — "text/plain". Рекомендуется оставить это значение без изменений, поскольку оно гарантирует, что любой получатель сможет прочитать письмо независимо от используемого почтового клиента. Однако, если вы уверены, что получатели могут обрабатывать другой тип содержимого, можно использовать атрибут content_subtype класса EmailMessage, чтобы изменить основной тип содержимого. Основной тип всегда будет "text", но подтип можно изменить. Например:
msg = EmailMessage(subject, html_content, from_email, [to]) msg.content_subtype = "html" # Main content is now text/html msg.send()
Бэкенды электронной почты
Непосредственная отправка электронной почты выполняется бэкендом электронной почты.
Класс бэкенда электронной почты имеет следующие методы:
-
open()создает долгоживущее соединение для отправки электронной почты. -
close()закрывает текущее соединение для отправки электронной почты. -
send_messages(email_messages)отправляет список объектовEmailMessage. Если соединение не открыто, этот вызов неявно откроет его и закроет после отправки. Если соединение уже открыто, после отправки почты оно останется открытым.
Его также можно использовать как менеджер контекста: в этом случае при необходимости будут автоматически вызваны open() и close():
from django.core import mail
with mail.get_connection() as connection:
mail.EmailMessage(
subject1,
body1,
from1,
[to1],
connection=connection,
).send()
mail.EmailMessage(
subject2,
body2,
from2,
[to2],
connection=connection,
).send()
Получение экземпляра бэкенда электронной почты
Функция get_connection() в django.core.mail возвращает экземпляр бэкенда электронной почты, который можно использовать.
-
get_connection(backend=None, *, fail_silently=False, **kwargs)[исходный код]
По умолчанию вызов get_connection() возвращает экземпляр бэкенда электронной почты, указанного в EMAIL_BACKEND. Если указать аргумент backend, будет создан экземпляр этого бэкенда.
Именованный аргумент fail_silently, который можно передать только по имени, определяет, как бэкенд должен обрабатывать ошибки. Если fail_silently имеет значение True, исключения, возникшие в процессе отправки электронной почты, будут молча игнорироваться.
Все остальные именованные аргументы напрямую передаются конструктору бэкенда электронной почты.
Django поставляется с несколькими бэкендами для отправки электронной почты. За исключением бэкенда SMTP (используемого по умолчанию), эти бэкенды полезны только при тестировании и разработке. Если у вас есть особые требования к отправке электронной почты, вы можете написать собственный бэкенд электронной почты.
Устарело с версии 6.0: Передача fail_silently в качестве позиционного аргумента устарела.
Бэкенд SMTP
-
class backends.smtp.EmailBackend(host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, use_ssl=None, timeout=None, ssl_keyfile=None, ssl_certfile=None, **kwargs) -
Это бэкенд, используемый по умолчанию. Электронная почта отправляется через сервер SMTP.
Значение каждого аргумента берется из соответствующей настройки, если аргумент равен
None:-
host:EMAIL_HOST -
port:EMAIL_PORT -
username:EMAIL_HOST_USER -
password:EMAIL_HOST_PASSWORD -
use_tls:EMAIL_USE_TLS -
use_ssl:EMAIL_USE_SSL -
timeout:EMAIL_TIMEOUT -
ssl_keyfile:EMAIL_SSL_KEYFILE -
ssl_certfile:EMAIL_SSL_CERTFILE
Бэкенд SMTP — это конфигурация, унаследованная Django по умолчанию. Чтобы указать его явно, добавьте в настройки следующее:
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
Если значение не указано, значением по умолчанию для
timeoutбудет значение, предоставляемоеsocket.getdefaulttimeout(); по умолчанию этоNone(без тайм-аута). -
Консольный бэкенд
Вместо отправки настоящих писем консольный бэкенд просто выводит письма, которые были бы отправлены, в стандартный поток вывода. По умолчанию консольный бэкенд записывает данные в stdout. Чтобы использовать другой объект, похожий на поток, передайте аргумент stream при создании соединения.
Чтобы указать этот бэкенд, добавьте в настройки следующее:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
Этот бэкенд не предназначен для использования в рабочей среде — он предоставлен для удобства и может применяться при разработке.
Файловый бэкенд
Файловый бэкенд записывает письма в файл. Для каждого нового сеанса, открытого с этим бэкендом, создается новый файл. Каталог для записи файлов берется либо из настройки EMAIL_FILE_PATH, либо из именованного аргумента file_path при создании соединения с помощью get_connection().
Чтобы указать этот бэкенд, добавьте в настройки следующее:
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend" EMAIL_FILE_PATH = "/tmp/app-messages" # change this to a proper location
Этот бэкенд не предназначен для использования в рабочей среде — он предоставлен для удобства и может применяться при разработке.
Бэкенд в памяти
Бэкенд 'locmem' сохраняет сообщения в специальном атрибуте модуля django.core.mail. Атрибут outbox создается при отправке первого сообщения. Это список, содержащий экземпляр EmailMessage для каждого письма, которое было бы отправлено.
Чтобы указать этот бэкенд, добавьте в настройки следующее:
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
Этот бэкенд не предназначен для использования в рабочей среде — он предоставлен для удобства и может применяться при разработке и тестировании.
Средство запуска тестов Django автоматически использует этот бэкенд для тестирования.
Пустой бэкенд
Как следует из названия, пустой бэкенд ничего не делает с вашими сообщениями. Чтобы указать этот бэкенд, добавьте в настройки следующее:
EMAIL_BACKEND = "django.core.mail.backends.dummy.EmailBackend"
Этот бэкенд не предназначен для использования в рабочей среде — он предоставлен для удобства и может применяться при разработке.
Определение пользовательского бэкенда электронной почты
Если вам нужно изменить способ отправки электронной почты, можно написать собственный бэкенд. В этом случае значением настройки EMAIL_BACKEND в файле настроек будет путь импорта Python для класса бэкенда.
Пользовательские бэкенды электронной почты должны быть подклассами BaseEmailBackend, расположенного в модуле django.core.mail.backends.base. Пользовательский бэкенд электронной почты должен реализовать метод send_messages(email_messages). Этот метод получает список экземпляров EmailMessage и возвращает количество успешно доставленных сообщений. Если в вашем бэкенде предусмотрен постоянный сеанс или соединение, следует также реализовать методы open() и close(). Пример реализации см. в smtp.EmailBackend.
Отправка нескольких писем
Установка и закрытие соединения SMTP (или любого другого сетевого соединения) — затратная операция. Если вам нужно отправить много писем, имеет смысл повторно использовать соединение SMTP, а не создавать и закрывать его каждый раз при отправке письма.
Есть два способа указать бэкенду электронной почты повторно использовать соединение.
Во-первых, можно использовать метод send_messages() для соединения. Он принимает список экземпляров EmailMessage (или подкласса) и отправляет их все через одно соединение. Поэтому любые значения connection, заданные для отдельных сообщений, игнорируются.
Например, если у вас есть функция get_notification_email(), возвращающая список объектов EmailMessage, представляющих периодические письма, которые вы хотите отправить, их можно отправить одним вызовом send_messages():
from django.core import mail connection = mail.get_connection() # Use default email connection messages = get_notification_email() connection.send_messages(messages)
В этом примере вызов send_messages() открывает соединение с бэкендом, отправляет список сообщений и затем закрывает соединение.
Второй подход — вручную управлять соединением с помощью методов open() и close() бэкенда электронной почты. send_messages() не открывает и не закрывает соединение вручную, если оно уже открыто, поэтому, открыв соединение вручную, вы можете самостоятельно определить, когда его закрыть. Например:
from django.core import mail
connection = mail.get_connection()
# Manually open the connection
connection.open()
# Construct an email message that uses the connection
email1 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to1@example.com"],
connection=connection,
)
email1.send() # Send the email
# Construct two more messages
email2 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to2@example.com"],
)
email3 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to3@example.com"],
)
# Send the two emails in a single call -
connection.send_messages([email2, email3])
# The connection was already open so send_messages() doesn't close it.
# We need to manually close the connection.
connection.close()
Настройка электронной почты для разработки
Иногда вы не хотите, чтобы Django вообще отправлял электронную почту. Например, при разработке сайта вам, вероятно, не нужно отправлять тысячи писем, однако вы можете захотеть проверить, что письма будут отправляться нужным людям при соответствующих условиях и содержать правильный текст.
Самый простой способ настроить электронную почту для локальной разработки — использовать консольный бэкенд электронной почты. Этот бэкенд перенаправляет всю почту в stdout, позволяя просматривать ее содержимое.
При разработке также может быть полезен файловый бэкенд электронной почты — он сохраняет содержимое каждого соединения SMTP в файл, который можно просмотреть в любое удобное время.
Еще один подход — использовать «фиктивный» сервер SMTP, который принимает письма локально и выводит их в терминал, но фактически ничего не отправляет. Пакет aiosmtpd позволяет это сделать:
python -m pip install "aiosmtpd >= 1.4.5" python -m aiosmtpd -n -l localhost:8025
Эта команда запустит минимальный сервер SMTP, который будет прослушивать порт 8025 на localhost. Сервер выводит в стандартный поток вывода все заголовки и текст писем. Затем вам останется указать соответствующие значения для настроек EMAIL_HOST и EMAIL_PORT. Более подробное описание параметров сервера SMTP см. в документации модуля aiosmtpd.
Сведения о модульном тестировании отправки электронной почты в приложении см. в разделе Службы электронной почты документации по тестированию.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/email/