actualización
Muchas gracias a Saqib Ali para resucitar esta vieja pregunta casi 5 años después de mi respuesta.
Las instrucciones que di en ese momento ya no funcionan. Sospecho que ha habido algunas mejoras en Django en los años intermedios, lo que significa que send_mail()
aplica texto sin formato. No importa lo que coloque en el contenido, siempre se entregará como texto sin formato.
El más reciente Django documentation explica que send_mail()
es en realidad sólo una conveniencia para la creación de una instancia de la clase django.core.mail.EmailMessage
y, a continuación, llamar send()
en esa instancia. EmailMessage
tiene esta nota para el parámetro de cuerpo, que explica los resultados que estamos viendo ahora en 2014:
cuerpo: El cuerpo del texto. Esto debería ser un mensaje de texto sin formato.
... algo más tarde en la documentación ...
Por defecto, el tipo MIME del cuerpo en un parámetro EmailMessage es "text/plain". Es una buena práctica dejar esto en paz.
Bastante (confieso que no me he tomado el tiempo para investigar por qué funcionó las instrucciones de 2009 - las probé en 2009 - o cuando cambiaron). Django proporciona, y document, una clase django.core.mail.EmailMultiAlternatives
para facilitar el envío de texto sin formato y representación HTML del mismo mensaje.
El caso en esta pregunta es ligeramente diferente. No buscamos agregar una alternativa per se, sino agregar partes relacionadas a una de las alternativas. Dentro de la versión HTML (y no importa si tiene u omite la versión de texto plano), queremos incrustar una parte de datos de imagen. No es una vista alternativa del contenido, sino contenido relacionado al que se hace referencia en el cuerpo HTML.
Todavía es posible enviar una imagen incrustada, pero no veo una manera directa de hacerlo usando send_mail
. Es hora de prescindir de la función de conveniencia y crear una instancia de EmailMessage
directamente.
Aquí es una actualización para el ejemplo anterior:
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()
respuesta original a partir de 2009:
Para enviar un correo electrónico con imágenes incrustadas, el uso de Python integrado en el módulo de correo electrónico para construir las partes MIME.
Lo siguiente debe hacerlo:
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")
En realidad, es probable que desee enviar el HTML junto con una alternativa de texto sin formato. En ese caso, use MIMEMultipart para crear el contenedor mimetype "relacionado" como raíz. A continuación, cree otro MIMEMultipart con el subtipo "alternativa" y adjunte un MIMEText (subtipo html) y un MIMEText (subtipo normal) a la parte alternativa. Luego adjunte la imagen a la raíz relacionada.
probé este código exacto y falló para mí: http://stackoverflow.com/ preguntas/21861593/how-can-i-send-inline-images-in-email-with-python-django –
Muchas gracias Jarret !! Esto funcionó como un campeón! –