Отправка электронной почты ¶
Хотя Python предоставляет интерфейс для отправки почты через smtplib
модуль, Django предоставляет пару легких оберток над ним. Эти оболочки предназначены для ускорения отправки электронной почты, для помощи в тестировании отправки электронной почты во время разработки и для обеспечения поддержки платформ, которые не могут использовать SMTP.
Код живет в django.core.mail
модуле.
Быстрый пример ¶
В двух строках:
from django.core.mail import send_mail
send_mail(
'Subject here',
'Here is the message.',
'[email protected]',
['[email protected]'],
fail_silently=False,
)
Почта отправляется с помощью 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
( При условии , сообщение , FROM_EMAIL , recipient_list , fail_silently не = False , AUTH_USER = нет , auth_password = нет , соединение = нет , 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
предусмотрено, полученное по электронной почте будет многочастному / альтернативный адрес электронной почты сmessage
как текст / обычный тип контента иhtml_message
как текст / html типа контента.
Возвращаемое значение будет количеством успешно доставленных сообщений (которое может быть 0
или может быть 1
отправлено только одно сообщение).
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
имеют те же функции, что и в send_mail()
.
Каждый отдельный элемент datatuple
результатов в отдельном сообщении электронной почты. Как и в случае send_mail()
, все получатели в одном и том же сообщении
recipient_list
будут видеть другие адреса в поле «Кому:» сообщения электронной почты.
Например, следующий код отправит два разных сообщения двум разным наборам получателей; однако будет открыто только одно соединение с почтовым сервером:
message1 = ('Subject here', 'Here is the message', '[email protected]', ['[email protected]', '[email protected]'])
message2 = ('Another Subject', 'Here is another message', '[email protected]', ['[email protected]'])
send_mass_mail((message1, message2), fail_silently=False)
Возвращаемое значение будет количеством успешно доставленных сообщений.
send_mass_mail()
против send_mail()
¶
Основное различие между send_mass_mail()
и
send_mail()
заключается в том, что
send_mail()
при каждом запуске открывается соединение с почтовым сервером, а send_mass_mail()
для всех своих сообщений используется одно соединение. Это делает
send_mass_mail()
немного более эффективным.
mail_admins()
¶
-
mail_admins
( тема , сообщение , fail_silently = False , connection = None , html_message = None ) ¶
django.core.mail.mail_admins()
- это ярлык для отправки электронной почты администраторам сайта, как определено в ADMINS
настройках.
mail_admins()
ставит префикс темы значением
EMAIL_SUBJECT_PREFIX
параметра, который установлен по умолчанию."[Django] "
Заголовок «От:» электронного письма будет значением
SERVER_EMAIL
настройки.
Этот метод существует для удобства и удобочитаемости.
Если html_message
предусмотрено, полученное по электронной почте будет
многочастному / альтернативный адрес электронной почты с message
как
текст / обычный тип контента и html_message
как
текст / html типа контента.
mail_managers()
¶
-
mail_managers
( тема , сообщение , fail_silently = False , connection = None , html_message = None ) ¶
django.core.mail.mail_managers()
точно так же mail_admins()
, за исключением того, что он отправляет электронное письмо менеджерам сайта, как определено в MANAGERS
настройке.
Примеры ¶
Это отправляет одно электронное письмо на адрес john @ example . com и jane @ example . com , причем оба они появляются в поле «Кому:»:
send_mail(
'Subject',
'Message.',
'[email protected]',
['[email protected]', '[email protected]'],
)
Это отправляет сообщение john @ example . com и jane @ example . com , и они оба получат отдельное электронное письмо:
datatuple = (
('Subject', 'Message.', '[email protected]', ['[email protected]']),
('Subject', 'Message.', '[email protected]', ['[email protected]']),
)
send_mass_mail(datatuple)
Предотвращение внедрения заголовка ¶
Внедрение заголовков - это средство защиты, при котором злоумышленник вставляет дополнительные заголовки электронной почты для управления полями «Кому:» и «От:» в сообщениях электронной почты, создаваемых вашими сценариями.
Все функции электронной почты Django, описанные выше, защищают от внедрения заголовков, запрещая символы новой строки в значениях заголовков. Если какой - либо subject
, from_email
или
recipient_list
содержит символ перевода строки (в любой Unix, Windows или Mac стиль), функция электронной почты (например send_mail()
) будет поднимать
django.core.mail.BadHeaderError
(подкласс ValueError
) и, следовательно, не будет посылать по электронной почте. Вы обязаны проверить все данные перед их передачей функциям электронной почты.
Если a message
содержит заголовки в начале строки, заголовки будут напечатаны как первый бит сообщения электронной почты.
Вот пример мнение , что берет subject
, message
и from_email
из данных POST по просьбе, в посылает , что админ @ пример . com и перенаправляет на «/ contact / thanks /», когда это будет сделано:
from django.core.mail import BadHeaderError, 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, ['[email protected]'])
except BadHeaderError:
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.')
EmailMessage
Класс ¶
Django's send_mail()
и
send_mass_mail()
функции на самом деле являются тонкими оболочками, которые используют этот EmailMessage
класс.
Не все возможности EmailMessage
класса доступны через send_mail()
функции-оболочки и связанные с ними функции-оболочки. Если вы хотите использовать расширенные функции, такие как получатели с скрытой копией, вложения файлов или электронное письмо, состоящее из нескольких частей, вам необходимо создать
EmailMessage
экземпляры напрямую.
Примечание
Это особенность дизайна. send_mail()
и связанные с ним функции изначально были единственным интерфейсом, предоставляемым Django. Однако список принимаемых ими параметров со временем медленно расширялся. Имеет смысл перейти к более объектно-ориентированному дизайну сообщений электронной почты и сохранить исходные функции только для обратной совместимости.
EmailMessage
отвечает за создание самого сообщения электронной почты. Электронный бэкенд затем отвечает за отправку по электронной почте.
Для удобства EmailMessage
предоставляет send()
способ отправки одного электронного письма. Если вам нужно отправить несколько сообщений, альтернативный API-интерфейс электронной почты предоставляет альтернативу .
EmailMessage
Объекты ¶
-
класс
EmailMessage
¶
EmailMessage
Класс инициализируется со следующими параметрами (в указанном порядке, если используются позиционные аргументы). Все параметры необязательны и могут быть установлены в любое время до вызова
send()
метода.
subject
: Тема письма.body
: Основной текст. Это должно быть текстовое сообщение.from_email
: Адрес отправителя. Как[email protected]
и формы законны. Если не указано, используется настройка."Fred" <[email protected]>
DEFAULT_FROM_EMAIL
to
: Список или кортеж адресов получателей.bcc
: Список или кортеж адресов, используемых в заголовке «Скрытая копия» при отправке электронного письма.connection
: Серверный экземпляр электронной почты. Используйте этот параметр, если вы хотите использовать одно и то же соединение для нескольких сообщений. Если не указано, приsend()
вызове создается новое соединение .attachments
: Список вложений, которые нужно вложить в сообщение. Это могут быть какMIMEBase
экземпляры, так и тройки.(filename, content, mimetype)
headers
: Словарь дополнительных заголовков, добавляемых к сообщению. Ключи - это имя заголовка, значения - это значения заголовка. Вызывающий абонент должен убедиться, что имена и значения заголовков имеют правильный формат для сообщения электронной почты. Соответствующий атрибут -extra_headers
.cc
: Список или кортеж адресов получателей, используемых в заголовке «Копия» при отправке электронного письма.reply_to
: Список или кортеж адресов получателей, используемых в заголовке «Reply-To» при отправке электронного письма.
Например:
from django.core.mail import EmailMessage
email = EmailMessage(
'Hello',
'Body goes here',
'[email protected]',
['[email protected]', '[email protected]'],
['[email protected]'],
reply_to=['[email protected]'],
headers={'Message-ID': 'foo'},
)
В классе есть следующие методы:
send(fail_silently=False)
отправляет сообщение. Если соединение было указано при создании электронного письма, оно будет использоваться. В противном случае будет создан и использован экземпляр серверной части по умолчанию. Если аргумент ключевого словаfail_silently
равенTrue
, исключения, возникающие при отправке сообщения, будут аннулированы. Пустой список получателей не вызовет исключения. Он вернется,1
если сообщение было отправлено успешно, в противном случае0
.message()
создаетdjango.core.mail.SafeMIMEText
объект (подкласс класса PythonMIMEText
) илиdjango.core.mail.SafeMIMEMultipart
объект, содержащий отправляемое сообщение. Если вам когда-нибудь понадобится расширитьEmailMessage
класс, вы, вероятно, захотите переопределить этот метод, чтобы поместить желаемое содержимое в объект MIME.recipients()
возвращает список всех получателей сообщения, независимо от того, записаны ли они в атрибутахto
,cc
илиbcc
. Это еще один метод, который вам может потребоваться переопределить при создании подкласса, потому что SMTP-серверу необходимо сообщить полный список получателей при отправке сообщения. Если вы добавите другой способ указать получателей в своем классе, их также нужно будет вернуть из этого метода.attach()
создает новое вложение файла и добавляет его к сообщению. Позвонить можно двумя способамиattach()
:Вы можете передать ему единственный аргумент, который является
MIMEBase
экземпляром. Он будет вставлен прямо в результирующее сообщение.Кроме того , вы можете передать
attach()
три аргумента:filename
,content
иmimetype
.filename
- это имя прикрепленного файла, которое будет отображаться в электронном письме,content
это данные, которые будут содержаться внутри вложения, иmimetype
является необязательным типом MIME для вложения. Если вы не укажетеmimetype
этот параметр, тип содержимого MIME будет определяться по имени файла вложения.Например:
message.attach('design.png', img_data, 'image/png')
Если указать
mimetype
в сообщении / rfc822 , он также будет приниматьdjango.core.mail.EmailMessage
иemail.message.Message
.Для
mimetype
начала с текста / ожидается, что содержимое будет строкой. Двоичные данные будут декодированы с использованием UTF-8, и если это не удастся, тип MIME будет изменен на application / octet-stream, и данные будут прикреплены без изменений.Кроме того, вложения message / rfc822 больше не будут кодироваться в кодировке base64 в нарушениеRFC 2046 # section-5.2.1 , что может вызвать проблемы с отображением вложений в Evolution и Thunderbird .
attach_file()
создает новое вложение, используя файл из вашей файловой системы. Вызовите его, указав путь к прикрепляемому файлу и, при желании, тип MIME, который будет использоваться для прикрепления. Если тип MIME опущен, он будет угадан по имени файла. Вы можете использовать это так:message.attach_file('/images/weather_map.png')
Для типов MIME, начинающихся с text / , двоичные данные обрабатываются как в
attach()
.
Отправка альтернативных типов контента ¶
Может быть полезно включить в электронное письмо несколько версий содержимого; классический пример - отправка как текстовой, так и HTML-версии сообщения. С помощью библиотеки электронной почты Django вы можете сделать это с помощью EmailMultiAlternatives
класса. Этот подкласс EmailMessage
имеет
attach_alternative()
метод для включения дополнительных версий тела сообщения в электронное письмо. Все остальные методы (включая инициализацию класса) наследуются напрямую от EmailMessage
.
Чтобы отправить комбинацию текста и HTML, вы можете написать:
from django.core.mail import EmailMultiAlternatives
subject, from_email, to = 'hello', '[email protected]', '[email protected]'
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()
По умолчанию, тип 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 , * args , ** kwargs ) ¶
По умолчанию при вызове get_connection()
будет возвращен экземпляр серверной части электронной почты, указанной в EMAIL_BACKEND
. Если вы укажете
backend
аргумент, будет создан экземпляр этого внутреннего интерфейса.
В fail_silently
управляет аргумент , как базовая программа должна обрабатывать ошибки. Если fail_silently
установлено значение True, исключения в процессе отправки электронной почты будут игнорироваться.
Все остальные аргументы передаются непосредственно конструктору серверной части электронной почты.
Django поставляется с несколькими серверными модулями для отправки электронной почты. За исключением бэкэнда SMTP (который используется по умолчанию), эти бэкэнды полезны только во время тестирования и разработки. Если у вас есть особые требования к отправке электронной почты, вы можете написать свой собственный сервер электронной почты .
Серверная часть 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
Этот бэкэнд не предназначен для использования в производственной среде - он предоставляется для удобства и может использоваться во время разработки.
Поддержка pathlib.Path
была добавлена.
Бэкэнд в памяти ¶
В '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()
методом. send_messages()
принимает список EmailMessage
экземпляров (или подклассов) и отправляет их все, используя одно соединение.
Например, если у вас есть вызываемая функция, 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',
'[email protected]',
['[email protected]'],
connection=connection,
)
email1.send() # Send the email
# Construct two more messages
email2 = mail.EmailMessage(
'Hello',
'Body goes here',
'[email protected]',
['[email protected]'],
)
email3 = mail.EmailMessage(
'Hello',
'Body goes here',
'[email protected]',
['[email protected]'],
)
# 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 отправлял электронные письма. Например, при разработке веб-сайта вы, вероятно, не захотите рассылать тысячи электронных писем, но вы можете убедиться, что электронные письма будут отправлены нужным людям при правильных условиях и что эти электронные письма будут содержать правильный контент. .
Самый простой способ настроить электронную почту для локальной разработки - использовать серверную часть электронной почты консоли . Этот бэкэнд перенаправляет всю электронную почту на стандартный вывод, позволяя вам проверять содержимое почты.
Бэкэнд файловой электронной почты также может быть полезен во время разработки - этот бэкэнд выгружает содержимое каждого SMTP-соединения в файл, который можно проверить на досуге.
Другой подход - использовать «тупой» SMTP-сервер, который принимает электронные письма локально и отображает их на терминал, но на самом деле ничего не отправляет. В Python есть встроенный способ сделать это с помощью одной команды:
python -m smtpd -n -c DebuggingServer localhost:1025
Эта команда запустит минимальный SMTP-сервер, прослушивающий порт 1025 localhost. Этот сервер выводит на стандартный вывод все заголовки и тело письма. Затем вам нужно только установить EMAIL_HOST
и
EMAIL_PORT
соответственно. Более подробное обсуждение параметров SMTP-сервера см. В документации Python к smtpd
модулю.
Информацию о модульном тестировании отправки электронных писем в вашем приложении см. В разделе « Службы электронной почты » документации по тестированию.