Python / Djangoで送信する画像を含むMIMEメールテンプレートを作成する
質問
私の Web アプリケーションでは、次のような再利用可能なメーラー アプリケーションを使用して電子メールを送信することがあります。
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" )
画像を埋め込んだメールを送信したいので、メール クライアントでメールを作成し、ソースを表示してテンプレート (welcome.eml) に入れようとしましたが、レンダリングできませんでした。送信時にメールクライアントで正しく動作します。
送信時に正しく表示される、インライン画像を含む MIME エンコードされたメール テンプレートを作成する簡単な方法を知っている人はいますか?
解決
アップデート
どうもありがとうございました サクイブ・アリ 私の回答からほぼ 5 年後にこの古い質問を復活させてくれてありがとう。
あの時の指示はもう通用しません。この間に Django にいくつかの改良が加えられたのではないかと思います。 send_mail()
プレーンテキストを強制します。コンテンツに何を入力しても、常にプレーンテキストとして配信されます。
最新の Django のドキュメント それを説明します send_mail()
これは実際には、のインスタンスを作成するための単なる便宜です。 django.core.mail.EmailMessage
クラス、そして呼び出し send()
そのインスタンスについて。 EmailMessage
body パラメーターに関する次のメモがあり、2014 年の現在確認されている結果を説明しています。
体:本文。これはプレーンテキストメッセージである必要があります。
...ドキュメントの少し後の部分で...
デフォルトでは、EmailMessage の body パラメータの MIME タイプは「text/plain」です。これはそのままにしておくのが得策です。
十分に公平です(2009 年の指示が機能した理由を調査する時間を取らなかったことを告白します。2009 年にテストしました。またはいつ変更されたのかを調べました)。Django は提供します。 書類, 、 django.core.mail.EmailMultiAlternatives
クラスを使用して、同じメッセージのプレーン テキストと HTML 表現を簡単に送信できるようにします。
この質問の場合は少し異なります。私たちは代替案そのものを追加することを求めているのではなく、代替案を追加することを目指しています。 関連している 部品を代替案の 1 つに追加します。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, 'foo@bar.com', ['bar@foo.com'])
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 を使用して、「関連する」MIME タイプ コンテナをルートとして作成します。次に、サブタイプ「alternative」を持つ別の MIMEMultipart を作成し、MIMEText (サブタイプ html) と MIMEText (サブタイプ plain) の両方を代替パートに添付します。次に、関連するルートにイメージをアタッチします。
他のヒント
Django 1.10でのJarretのレシピに問題がありました-MIMEデータを添付するさまざまな方法でMIMEおよびエンコードエラーを取得していました。
django 1.10で動作する coupon_image
ファイルオブジェクトが埋め込まれた電子メール用のシンプルなマルチパートトランザクションテンプレートを次に示します。
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)