إنشاء قالب بريد إلكتروني MIME يحتوي على صور لإرسالها باستخدام python/Django

StackOverflow https://stackoverflow.com/questions/1633109

  •  06-07-2019
  •  | 
  •  

سؤال

في تطبيق الويب الخاص بي، أرسل رسائل بريد إلكتروني أحيانًا باستخدام تطبيق بريدي قابل لإعادة الاستخدام مثل هذا:

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() يفرض نص عادي.بغض النظر عما تضعه في المحتوى، فسيتم تسليمه دائمًا كنص عادي.

الأحدث وثائق جانغو يوضح ذلك send_mail() هو في الحقيقة مجرد وسيلة راحة لإنشاء مثيل لـ django.core.mail.EmailMessage الطبقة، ومن ثم الاتصال send() على تلك الحالة. EmailMessage يحتوي على هذه الملاحظة الخاصة بمعلمة الجسم، والتي تشرح النتائج التي نشهدها الآن في عام 2014:

جسم:النص الجسدي.يجب أن تكون هذه رسالة نصية عادية.

...في وقت لاحق إلى حد ما في المستندات ...

افتراضيًا، يكون نوع MIME لمعلمة النص في EmailMessage هو "نص/عادي".من الممارسات الجيدة ترك هذا الأمر بمفرده.

عادل بما فيه الكفاية (أعترف أنني لم أخصص الوقت الكافي للتحقيق في سبب نجاح تعليمات 2009 - فقد قمت باختبارها مرة أخرى في عام 2009 - أو عندما تغيرت).جانغو لا يوفر، و وثيقة, ، أ django.core.mail.EmailMultiAlternatives class لتسهيل إرسال نص عادي وتمثيل 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, '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:

لإرسال بريد إلكتروني يحتوي على صور مضمنة، استخدم وحدة البريد الإلكتروني المضمنة في بايثون لبناء أجزاء 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 (النوع الفرعي العادي) بالجزء البديل.ثم قم بإرفاق الصورة بالجذر ذي الصلة.

نصائح أخرى

وكنت أعاني من مشاكل مع وصفة جارت على جانغو 1.10 - تم الحصول على أخطاء MIME والترميز لمختلف الطرق التي يمكن أن نعلق البيانات MIME

.

إليك قالب المعاملات متعدد الأجزاء بسيط لرسالة بريد إلكتروني مع كائن ملف coupon_image جزءا لا يتجزأ من أن يعمل على جانغو 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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top