Ответ 1
Обновление
Большое спасибо Saqib Ali за воскрешение этого старого вопроса почти через 5 лет после моего ответа.
Инструкции, которые я дал в то время, больше не работают. Я подозреваю, что в течение нескольких лет в Django были некоторые улучшения, которые означают, что send_mail()
применяет простой текст. Независимо от того, что вы вкладываете в контент, он всегда будет передаваться как обычный текст.
Самая последняя документация Django объясняет, что send_mail()
действительно просто удобство для создания экземпляра класса django.core.mail.EmailMessage
и затем вызывает send()
в этом экземпляре. EmailMessage
имеет эту заметку для параметра body, что объясняет результаты, которые мы видим сейчас в 2014 году:
Тело: текст тела. Это должно быть текстовое сообщение.
... несколько позже в документах...
По умолчанию MIME-тип параметра body в EmailMessage является "text/plain". Это хорошая практика, чтобы оставить это в покое.
Достаточно честный (я признаюсь, что не нашел времени, чтобы выяснить, почему работала инструкция 2009 года - я проверила их еще в 2009 году или когда она изменилась). Django предоставляет и document, класс django.core.mail.EmailMultiAlternatives
, чтобы упростить отправку обычного текста и представления HTML одного и того же сообщения.
Случай в этом вопросе несколько отличается. Мы не пытаемся добавить альтернативу как таковую, но добавим связанные части к одной из альтернатив. В HTML-версии (и не имеет значения, есть ли у вас или нет версия простого текста), мы хотим внедрить часть данных изображения. Не альтернативный вид содержимого, а связанный контент, на который ссылается в теле HTML.
Отправка встроенного изображения по-прежнему возможна, но я не вижу прямого способа сделать это, используя send_mail
. Пришло время отказаться от функции удобства и создать экземпляр EmailMessage
напрямую.
Здесь обновление к предыдущему примеру:
from django.core.mail import EmailMessage
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# Load the image you want to send as bytes
img_data = open('logo.jpg', 'rb').read()
# Create a "related" message container that will hold the HTML
# message and the image. These are "related" (not "alternative")
# because they are different, unique parts of the HTML message,
# not alternative (html vs. plain text) views of the same content.
html_part = MIMEMultipart(_subtype='related')
# Create the body with HTML. Note that the image, since it is inline, is
# referenced with the URL cid:myimage... you should take care to make
# "myimage" unique
body = MIMEText('<p>Hello <img src="cid:myimage" /></p>', _subtype='html')
html_part.attach(body)
# Now create the MIME container for the image
img = MIMEImage(img_data, 'jpeg')
img.add_header('Content-Id', '<myimage>') # angle brackets are important
img.add_header("Content-Disposition", "inline", filename="myimage") # David Hess recommended this edit
html_part.attach(img)
# Configure and send an EmailMessage
# Note we are passing None for the body (the 2nd parameter). You could pass plain text
# to create an alternative part for this message
msg = EmailMessage('Subject Line', None, '[email protected]', ['[email protected]'])
msg.attach(html_part) # Attach the raw MIMEBase descendant. This is a public method on EmailMessage
msg.send()
Оригинальный ответ от 2009 года:
Чтобы отправить электронное письмо со встроенными изображениями, используйте встроенный модуль электронной почты python для создания частей MIME.
Следующее должно сделать это:
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# Load the image you want to send at bytes
img_data = open('logo.jpg', 'rb').read()
# Create a "related" message container that will hold the HTML
# message and the image
msg = MIMEMultipart(_subtype='related')
# Create the body with HTML. Note that the image, since it is inline, is
# referenced with the URL cid:myimage... you should take care to make
# "myimage" unique
body = MIMEText('<p>Hello <img src="cid:myimage" /></p>', _subtype='html')
msg.attach(body)
# Now create the MIME container for the image
img = MIMEImage(img_data, 'jpeg')
img.add_header('Content-Id', '<myimage>') # angle brackets are important
msg.attach(img)
send_mail(subject, msg.as_string(), from, [to], priority="high")
В действительности вы, вероятно, захотите отправить HTML вместе с альтернативой обычного текста. В этом случае используйте MIMEMultipart для создания "родственного" контейнера mimetype в качестве корня. Затем создайте еще один MIMEMultipart с подтипом "альтернативный" и прикрепите к альтернативной части как MIMEText (подтип html), так и MIMEText (подтип). Затем присоедините изображение к соответствующему корню.