django send_mail功能

咱們知道python中smtplib模塊用於郵件的功能,而django對這個這模塊進行封裝,使得它使用起來十分簡單。 django.core.mail就是django郵件的核心模塊。html

兩個經常使用函數

它提供了兩個函數,使用起來十分的簡單:python

def send_mail(subject, message, from_email, recipient_list,
              fail_silently=False, auth_user=None, auth_password=None,
              connection=None, html_message=None):
    pass          
    
            
def send_mass_mail(datatuple, fail_silently=False, auth_user=None,
                   auth_password=None, connection=None):
    pass

# 參數介紹 
# subject: 郵件主題 
# message: 郵件內容 
# from_email: 發件人 
# recipient_list: 收件人,這是一個列表,能夠有多個收件人 
# 以上4個在參數 在send_mass_mail中,會寫在datatuple這個元組中 
# fail_silently: 是否報錯,True的話表忽略異常 
# auth_user&auth_password:帳號密碼 
# connection: 表示這個的連接對象,後續會提到 
# html_message: send_mail方法獨有,能夠比較簡單地實現一個html文本的傳輸,具體我也沒使用過,不是很瞭解。
複製代碼

通常狀況下,咱們須要在setting中進行配置,除了必須配置的host和port,通常咱們也將帳號密碼寫在這裏,這樣每次調用函數就不用傳遞這兩個參數,當不傳遞這兩個值,他們就會默認去讀取setting中的值
返回值是成功發送了多個message,而不是多少我的,通常使用send_mail,都返回1git

# settings.py
# 我使用的是新浪的,host能夠在對應郵箱的設置中找到
EMAIL_HOST = 'smtp.sina.com'
EMAIL_PORT = 25
# 你的郵箱帳號與密碼
EMAIL_HOST_USER = 'viptestfordjango@sina.com'
EMAIL_HOST_PASSWORD = '******'
# 因爲使用25端口,通常都不使用TLS機密,SSL和TSL只須要設置一個,他們同時爲True或False
EMAIL_USE_TLS = False
# 發件人,只有這個變量名能夠本身自定義,設置在這裏是爲了減小每次去寫
EMAIL_FROM = 'viptestfordjango@sina.com'
複製代碼

實例

from django.core.mail import send_mail, send_mass_mail
from string import lowercase,uppercase,digits
from random import randint
from project.settings import EMAIL_FROM
def send_code_email(email):
    """ 發送驗證碼 """
    # 0-9 a-z A-z
    code = ''
    seeds= lowercase+uppercase+digits
    length = len(seeds)
    # 生成4位驗證碼
    for i in range(4):
        code += seeds[randint(0, length-1)]
    send_title = '重置密碼'
    send_message = '你的驗證碼是:{0}。'.format(code)
    send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])


def send_hello_email(email1, email2):
    """ 給email1發送 新年好 給email2發送 Happy New Year """
    # message格式(subject, message, from_email, recipient_list)
    message1 = ('新年好', '新年好', 'EMAIL_FROM', [email])
    message2 = ('Happy New Year', 'Happy New Year', EMAIL_FROM, [email2])
    send_status=send_mass_mail((message1, message2), fail_silently=False)
複製代碼

很明顯能夠看出2個函數的不一樣,send_mail一次發送一個message(給多人),而send_mass_mail一次能夠發送不一樣的message(給多人)。
更深層的理解,前面提升一個參數connection,結合這個參數,其實每創建一個鏈接,send_mail只發送一種message,而send_mass_mail創建一個鏈接,能夠發送多個message,這樣子,效率明顯高不少。django

高級功能

前面2個函數實際上是對EmailMessage這個類進行封裝,使他們使用起來,至關的簡單,但它們的功能是十分有限的,例如,沒法抄送(cc)或者私密發送(bcc)以及沒法加入附件(attachments)
若是要是用剛剛說的功能,就必須直接使用EmailMessage這個類。bash

EmailMessage

# 類定義
class EmailMessage(object):
    def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
                 connection=None, attachments=None, headers=None, cc=None,
                 reply_to=None):
    pass
    
# 使用
from django.core.mail import EmailMessage

email = EmailMessage(
    'Hello',
    'Body goes here',
    'from@example.com',
    ['to1@example.com', 'to2@example.com'],
    ['bcc@example.com'],
    reply_to=['another@example.com'],
    headers={'Message-ID': 'foo'},
)
複製代碼

這個類參數中,抄送cc,私密發送bcc,回覆reply_to都是一個列表。
值得一提的是attachments,它也是一個列表,它的元素始:MIMEBase對象或者(filename, content, mimetype)這個元組,即包括顯示的文件名,文件數據,文件類型。
它還提供一些方法,主要提2個:send()發送郵件,以及attach()添加附件app

直接使用Backend

若是咱們像上面那樣直接去調用EmailMessage.send(),這樣一次鏈接connection就只會發送一個message,那麼若是我想發送多個message呢?
這個時候咱們就有必要去了解backend了
其實django sending_email功能是由backend的控制的,這個類提供幾個方法:
open(): 開個一個鏈接
close(): 關閉這個鏈接
send_messages(email_messages): 接受一個EmailMessage對象的列表,而後將多個信息發送出去,而EmailMessage的send()方法就是調用這個方法,只是傳遞的參數是[self],就只有一個對象。
那麼,其實若是咱們能控制connection的開關,那麼咱們就能實現多個EmailMessage對象在email發送出去,這個時候,咱們考慮經過上下文自動控制打開與關閉操做的方式:dom

from django.core import mail

with mail.get_connection() as connection:
    mail.EmailMessage(
        subject1, body1, from1, [to1],
        connection=connection,
    ).send()
    mail.EmailMessage(
        subject2, body2, from2, [to2],
        connection=connection,
    ).send()

複製代碼

這樣的方法顯得有點笨拙,咱們確定但願可以使用send_messages(),直接傳遞一個EmailMessage對象的列表給它。咱們注意到上面的代碼get_connection()函數,其實它就是可以直接去獲取到一個backend的對象,而後經過直接調用這個send_messages()方法。函數

from django.core import mail

connection = mail.get_connection()
# get_EmailMessage_list返回一個EmailMessage對象的列表
messages = get_EmailMessage_list()
connection.send_messages(messages)
複製代碼

這個直接調用send_messages(messages),若是此時沒有open連接的話,它會先打開鏈接,執行關自動關閉。spa

這樣子好像還有點不靈活,那也能夠親自控制open與close!code

from django.core import mail

connection = mail.get_connection()
connection.open()

email1 = mail.EmailMessage(
    'Hello',
    'Body goes here',
    'from@example.com',
    ['to1@example.com'],
    connection=connection,
)
email1.send() 

email2 = mail.EmailMessage(
    'Hello',
    'Body goes here',
    'from@example.com',
    ['to2@example.com'],
)
email3 = mail.EmailMessage(
    'Hello',
    'Body goes here',
    'from@example.com',
    ['to3@example.com'],
)
connection.send_messages([email2, email3])

connection.close()
複製代碼

這個例子使用EmailMessage.send()與connection.send_messages()的使用,這個只是展現做用,並沒用必要同時使用

backend類型與定製

說了那麼多的backend,那它究竟是什麼,其實默認的它就是:backends.smtp.EmailBackend

# 在django.core.mail。backends.smtp.下
class EmailBackend(BaseEmailBackend):

    def __init__(self, host=None, port=None, username=None, password=None,
                 use_tls=None, fail_silently=False, use_ssl=None, timeout=None,
                 ssl_keyfile=None, ssl_certfile=None,**kwargs):
        pass
複製代碼

就是這個類,它繼承BaseEmailBackend了,是默認的backend,控制了整個send mail的過程,固然django還提供了其餘backend,不過做用不是很大。
Console backend: 將郵件直接寫到你的stdout中。
Dummy backend: 沒有實際做用。
你只須要在setting中指定你的backend:

EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
複製代碼

固然,還能夠自定義backend,你須要繼承BaseEmailBackend,而且實現send_messages(email_messages),open,close方法,不過我感受沒有這個必要,畢竟smtp.EmailBackend提供了較爲完善的功能了。

後言

本文內容基原本自django1.11官方文檔,文字部分都是基於文檔與本身的理解,可能會存在理解錯誤,歡迎各位的指出。

參考文章:
  django1.11官方文檔 email

相關文章
相關標籤/搜索