Pergunta

Na minha aplicação web que enviar e-mails ocasionalmente usando um aplicativo mailer reutilizável assim:

user - self.user
subject = ("My subject")
from = "me@mydomain.com"
message = render_to_string("welcomeEmail/welcome.eml", { 
                "user" : user,
                })
send_mail(subject, message, from, [email], priority="high" )

Eu quero enviar um e-mail com imagens embutidas nele, então eu tentei fazer o e-mail em um cliente de email, visualização da fonte, e colocá-lo em meu modelo (welcome.eml), mas eu fui incapaz de obter -lo para processar corretamente em clientes de email quando seu enviado.

Alguém sabe de uma maneira fácil para mim criar mime codificado modelos de correio com imagens inline que irá processar corretamente quando eu enviá-los?

Foi útil?

Solução

Atualizar

Muito obrigado a Saqib Ali para ressuscitar esta velha questão quase 5 anos depois da minha resposta.

As instruções que eu dei na época não funcionam mais. Eu suspeito que tenha havido algumas melhorias para Django nos anos seguintes, o que significa que send_mail() impõe texto simples. Não importa o que você colocar no conteúdo, ele será sempre entregues como texto simples.

O mais recente Django documentação explica que send_mail() é realmente apenas uma conveniência para criar uma instância da classe django.core.mail.EmailMessage, e em seguida, chamando send() nessa instância. EmailMessage tem esta nota para o parâmetro do corpo, o que explica os resultados que estamos vendo agora em 2014:

corpo: O corpo do texto. Esta deve ser uma mensagem de texto simples.

... um pouco mais tarde nos docs ...

Por padrão, o tipo MIME do parâmetro corpo em um EmailMessage é "text / plain". É uma boa prática para deixar isso sozinho.

É justo (confesso que não tenham tomado a tempo para investigar por que as instruções 2009 trabalhou - Eu fiz teste-los de volta em 2009 - ou quando mudou). Django prevê, e documento , um classe django.core.mail.EmailMultiAlternatives para tornar mais fácil para enviar um texto simples e representação HTML da mesma mensagem.

O caso nesta questão é um pouco diferente. Nós não estamos tentando anexar uma alternativa per se, mas para acrescentar relacionadas peças para uma das alternativas. Dentro da versão HTML (e não importa se você tem ou omitir a versão em texto puro), que deseja incorporar uma parte de dados de imagem. Não é uma visão alternativa do conteúdo, mas relacionadas conteúdo que é referenciado no corpo HTML.

O envio de uma imagem incorporada ainda é possível, mas eu não vejo uma maneira simples de fazê-lo usando send_mail. É hora de dispensar com a função de conveniência e instanciar um EmailMessage diretamente.

Aqui está uma atualização para o exemplo 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, 'foo@bar.com', ['bar@foo.com'])
msg.attach(html_part) # Attach the raw MIMEBase descendant. This is a public method on EmailMessage
msg.send()

resposta original a partir de 2009:

Para enviar um e-mail com imagens embutidas, o uso de python módulo interno de e-mail para construir as partes MIME.

A seguir deve fazê-lo:

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")

Na realidade, você provavelmente vai querer enviar o HTML juntamente com uma alternativa de texto simples. Nesse caso, use MimeMultipart para criar o "relacionado" container mimetype como a raiz. Em seguida, crie outra MimeMultipart com o subtipo "alternativo", e anexar tanto um MimeText (subtipo html) e um MimeText (plain subtipo) para a parte alternativa. Em seguida, anexar a imagem à raiz relacionado.

Outras dicas

Eu estava tendo problemas com a receita de Jarret em Django 1.10 -. Estava ficando MIME e codificação erros para as várias maneiras que você pode anexar dados MIME

Aqui está uma simples multipart transacional modelo para um e-mail com um objeto de arquivo coupon_image incorporado que funciona em Django 1.10:

from django.core.mail import EmailMultiAlternatives
from email.mime.image import MIMEImage

def send_mail(coupon_image):
    params = {'foo':'bar'} # create a template context
    text_body = render_to_string('coupon_email.txt', params)
    html_body = render_to_string('coupon_email.html', params)
    img_data = coupon_image.read() #should be a file object, or ImageField
    img = MIMEImage(img_data)
    img.add_header('Content-ID', '<coupon_image>')
    img.add_header('Content-Disposition', 'inline', filename="coupon_image")

    email = EmailMultiAlternatives(
        subject="Here's your coupon!",
        body=text_body,
        from_email='noreply@example.com',
        to=['someone@example.com',]
    )

    email.attach_alternative(html_body, "text/html")
    email.mixed_subtype = 'related'
    email.attach(img)

    email.send(fail_silently=False)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top