我們知道python中smtplib模組用於郵件的功能,而django對這個這模組進行封裝,使得它使用起來十分簡單。 django.core.mail就是django郵件的核心模組。
兩個常用函式
它提供了兩個函式,使用起來十分的簡單:
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,都返回1
# 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,這樣子,效率明顯高很多。
高階功能
前面2個函式其實是對EmailMessage這個類進行封裝,使他們使用起來,相當的簡單,但它們的功能是十分有限的,例如,無法抄送(cc)或者私密傳送(bcc)以及無法加入附件(attachments)
如果要是用剛剛說的功能,就必須直接使用EmailMessage這個類。
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()新增附件
直接使用Backend
如果我們像上面那樣直接去呼叫EmailMessage.send(),這樣一次連線connection就只會傳送一個message,那麼如果我想傳送多個message呢?
這個時候我們就有必要去了解backend了
其實django sending_email功能是由backend的控制的,這個類提供幾個方法:
open(): 開個一個連線
close(): 關閉這個連線
send_messages(email_messages): 接受一個EmailMessage物件的列表,然後將多個資訊傳送出去,而EmailMessage的send()方法就是呼叫這個方法,只是傳遞的引數是[self],就只有一個物件。
那麼,其實如果我們能控制connection的開關,那麼我們就能實現多個EmailMessage物件在email傳送出去,這個時候,我們考慮通過上下文自動控制開啟與關閉操作的方式:
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連結的話,它會先開啟連線,執行關自動關閉。
這樣子好像還有點不靈活,那也可以親自控制open與close!
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