python測試開發django-30.發送附件EmailMessage


前言

Django的 send_mail() 和 send_mass_mail() 函式事實上是對 EmailMessage 類使用方式 的一個輕度封裝。send_mail() 和相關的其他封裝函式並沒有充分使用 EmailMessage 類的所有特性。
要想使用更多特性,比如暗送(BCC),加入附件,或是多用途格式(multi-part)郵件,都要直接創建 EmailMessage 實例。
有些資料用的EmailMultiAlternatives 類,有些用的 EmailMessage 類,這2個其實有關聯,EmailMultiAlternatives 類繼承了EmailMessage 類

EmailMessage

EmailMessage 類使用下列參數初始化(除非使用位置參數,否則默認順序如下)。所有參數均可選,均可在調用 send()方法之前的任何時間對其賦值。

  • subject: 郵件的標題行
  • body: 郵件的主體內容文本,須是純文本信息。
  • from_email: 發送者的地址。 fred@example.com 或 Fred fred@example.com 格式都是合法的。如果忽略該參數,Django就會使用 DEFAULT_FROM_EMAIL 配置項。
  • to: 收件人地址列表或元組。
  • bcc: 發送郵件時用於”Bcc”頭信息的一組列表或元組,也就是暗送的收件人
  • connection: 一個郵件后端實例。用同一個鏈接發送多封郵件就要用到該參數。忽略該參數時,會在調用 send() 時自動創建一個新鏈接。
  • attachments: 置於郵件報文內的附件列表。列表元素可以是 email.MIMEBase.MIMEBase 實例,也可以是(filename, content, mimetype) 三部分構成的元組。
  • headers: 置於郵件報文內的其他頭信息(header)的字典。字典的key是頭信息的名稱,字典的value是頭信息的值。 這樣做能確保頭信息的名稱和對應值會以正確的格式保存於郵件報文中。
  • cc: 發送郵件時放於”Cc”頭信息的一系列列表或元組。
  • reply_to:發送電子郵件時“回復”標題中使用的收件人地址列表或元組。
class EmailMessage:
    """A container for email information."""
    content_subtype = 'plain'
    mixed_subtype = 'mixed'
    encoding = None     # None => use settings default

    def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
                 connection=None, attachments=None, headers=None, cc=None,
                 reply_to=None):
        ...省略

    def send(self,fail_silently=False) :
         """
         發送郵件報文。如果在構造郵件時如果指定了某個鏈接(connection),就會使用該鏈接發郵件。 否則,就會使用默認后端的實例發郵件。
          如果關鍵字參數 fail_silently 為 True ,就會忽略郵件發送時拋出的異常。
         """
    def recipients(self):
        """
         返回郵件中所有收件人的列表,不管收件人是在 to 還是 bcc 屬性中。
         這是另一個經常被繼承覆寫的方法, 因為SMTP服務器在發送郵件報文時,要接收完整的收件人列表。
         即使你自己的類使用其他方式來指定收件人,也仍然需要使用該方法返回收件人列表。
        """

    def message(self) :
         """
         構造了一個 django.core.mail.SafeMIMEText 對象 (Python的 email.MIMEText.MIMEText 類的子類) 或是 django.core.mail.SafeMIMEMultipart 對象(該對象保存即將發送出去郵件報文)。
         如需擴展 EmailMessage類,一般情況下要覆寫該方法,將你所需的內容添加到MIME對象中。
         """

   def attach(self, filename=None, content=None, mimetype=None):
        """
         傳遞一個單獨的 email.MIMEBase.MIMEBase 實例做為參數。該實例會直接添加到最終的郵件報文中。

         或者,給 attach() 傳遞三個參數: filename, content 和 mimetype. filename 是出現在郵件中的附件文件的名稱, content 是附件的內容,而 mimetype 是附件所使用的MIME類型。 
         如果忽略 mimetype, Django會自動根據附件文件名來推測MIME內容類型。
         例如:
                 message.attach('design.png', img_data, 'image/png')
        """
    

     def attach_file(self, path, mimetype=None):
         """
         使用當前文件系統下的某個文件做為附件。調用時,傳入某個文件的完整路徑,以及該附件的MIME類型(可選的)。
         忽略MIME類型的話,Django會自動根據附件文件名來推測MIME類型。
         最簡單的用法如下:
         message.attach_file('/images/weather_map.png')
        """
       

attach_file方法傳文件

使用當前文件系統下的某個文件做為附件。調用時,傳入某個文件的完整路徑,這種方法是最簡單的,上傳本地的某個文件。
如在templates目錄下有一個a.png的圖片(圖片和其它文件都一樣,如xx.doc,只是后綴不一樣)

views.py文件實現代碼

from django.http import HttpResponse
from django.core.mail import send_mail, send_mass_mail
from django.core.mail import EmailMessage
import os


def file_mail(request):
    '''發送附件'''
    email = EmailMessage(
        'Hello',
        'Body goes here',
        '2833404xx@qq.com',   # 發件人
        ['2833404xx@qq.com', 'to2@example.com'],   # 收件人
        ['xxx@xxx.com'],                      # cc抄送
        reply_to=['another@example.com'],  # “回復”標題中使用的收件人地址列表或元組
        headers={'Message-ID': 'foo'},
    )
    cur = os.path.dirname(os.path.realpath(__file__))
    # templates目錄下有個a.png的圖片
    filepath = os.path.join(cur, "templates", "a.png")

    email.attach_file(filepath, mimetype=None)
    email.send()
    return HttpResponse('郵件發送成功,收不到就去垃圾箱找找吧!')

郵件收到效果如下

attach方法

attach() 傳遞三個參數: filename, content 和 mimetype. filename 是出現在郵件中的附件文件的名稱, content 是附件的內容,而 mimetype 是附件所使用的MIME類型。
參考格式如:message.attach('design.png', img_data, 'image/png')

from django.http import HttpResponse
from django.core.mail import send_mail, send_mass_mail
from django.core.mail import EmailMessage
import os


def file_mail(request):
    '''發送附件'''
    email = EmailMessage(
        'Hello',
        'Body goes here',
        '2833404xx@qq.com',   # 發件人
        ['2833404xx@qq.com', 'to2@example.com'],   # 收件人
        ['xxx@xx.com'],                      # cc抄送
        reply_to=['another@example.com'],  # “回復”標題中使用的收件人地址列表或元組
        headers={'Message-ID': 'foo'},
    )
    cur = os.path.dirname(os.path.realpath(__file__))
    # templates目錄下有個a.png的圖片
    file1 = os.path.join(cur, "templates", "a.png")

    # 方法1 attach_file
    email.attach_file(file1, mimetype=None)

    # 方法2 attach
    file2 = os.path.join(cur, "templates", "b.png")
    img_data = open(file2, "rb")
    email.attach('b.png', img_data.read(), 'image/png')

    email.send()
    return HttpResponse('郵件發送成功,收不到就去垃圾箱找找吧!')

郵件收到效果如下

這里雖然能添加附件了,但是如果正文想傳html的正文內容,這個類里面沒有封裝對應方法,在EmailMultiAlternatives類里面有個attach_alternative方法可以實現次功能,接着往下看

EmailMultiAlternatives

attach_alternative方法封裝在EmailMultiAlternatives類里面,EmailMultiAlternatives類繼承了EmailMessage類

class EmailMultiAlternatives(EmailMessage):
    """
    繼承EmailMessage 可以輕松發送multipart / alternative消息。 例如,包括文本的HTML和HTML版本變得更容易
    """
    alternative_subtype = 'alternative'

    def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
                 connection=None, attachments=None, headers=None, alternatives=None,
                 cc=None, reply_to=None):
        """
        Initialize a single email message (which can be sent to multiple
        recipients).
        """
        super().__init__(
            subject, body, from_email, to, bcc, connection, attachments,
            headers, cc, reply_to,
        )
        self.alternatives = alternatives or []

    def attach_alternative(self, content, mimetype):
        """Attach an alternative content representation."""
        assert content is not None
        assert mimetype is not None
        self.alternatives.append((content, mimetype))

使用方法

from django.http import HttpResponse
from django.core.mail import EmailMultiAlternatives
import os

def file_html_mail(request):
    '''發送附件+html正文'''
    email = EmailMultiAlternatives(
        'Hello',
        'Body goes here',
        '2833404xx@qq.com',   # 發件人
        ['2833404xx@qq.com', 'to2@example.com'],   # 收件人
        ['xxx@xxx.com'],                      # cc抄送
        reply_to=['another@example.com'],  # “回復”標題中使用的收件人地址列表或元組
        headers={'Message-ID': 'foo'},
    )
    cur = os.path.dirname(os.path.realpath(__file__))
    # templates目錄下有個a.png的圖片
    file1 = os.path.join(cur, "templates", "a.png")

    # 方法1 attach_file
    email.attach_file(file1, mimetype=None)

    # 方法2 attach
    file2 = os.path.join(cur, "templates", "b.png")
    img_data = open(file2, "rb")
    email.attach('b.png', img_data.read(), 'image/png')

    # 添加html正文
    h = '''
    <!DOCTYPE HTML>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>帶圖片的郵件</title>
    </head>
    <body>
    <a href="https://yuedu.baidu.com/ebook/902224ab27fff705cc1755270722192e4536582b" target="_blank">
        <p>pytest教程,點圖片進入:<br>
        <img src="https://img2018.cnblogs.com/blog/1070438/201902/1070438-20190228112918941-704279799.png" height="160" width="270" />
        </p></a>
    <p>
    其它圖片:<br>
    <img src="http://www.w3school.com.cn/i/eg_chinarose.jpg" height=150 width=300/></p>
    <p>請注意,插入動畫圖像的語法與插入普通圖像的語法沒有區別。</p>
    </body>
    </html>
    '''
    email.attach_alternative(content=h, mimetype="text/html")
    email.send()
    return HttpResponse('郵件發送成功,收不到就去垃圾箱找找吧!')

到這里郵件發送相關的功能都實現了

總的來說,一般推薦用EmailMultiAlternatives類,它繼承了EmailMessage


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM