django中send_mail功能实现详解


Posted in Python onFebruary 06, 2018

前言

我们大家应该都知道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

Python 相关文章推荐
用python写asp详细讲解
Dec 16 Python
python自动翻译实现方法
May 28 Python
Python 函数基础知识汇总
Mar 09 Python
numpy.transpose对三维数组的转置方法
Apr 17 Python
tensorflow 获取模型所有参数总和数量的方法
Jun 14 Python
Python tkinter的grid布局及Text动态显示方法
Oct 11 Python
Matplotlib中文乱码的3种解决方案
Nov 15 Python
解决pycharm 工具栏Tool中找不到Run manager.py Task的问题
Jul 01 Python
Python运行提示缺少模块问题解决方案
Apr 02 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
Jul 13 Python
Python Pandas知识点之缺失值处理详解
May 11 Python
pytorch中[..., 0]的用法说明
May 20 Python
Python打印“菱形”星号代码方法
Feb 05 #Python
Django权限机制实现代码详解
Feb 05 #Python
Django中的Signal代码详解
Feb 05 #Python
Python实现XML文件解析的示例代码
Feb 05 #Python
Python下载网络文本数据到本地内存的四种实现方法示例
Feb 05 #Python
Python实现屏幕截图的两种方式
Feb 05 #Python
Python实现连接两个无规则列表后删除重复元素并升序排序的方法
Feb 05 #Python
You might like
php中字符集转换iconv函数使用总结
2014/10/11 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
javascript 遍历验证所有文本框的值
2009/08/27 Javascript
JavaScript Event学习第三章 早期的事件处理程序
2010/02/07 Javascript
JQUERY 实现窗口滚动搜索框停靠效果(类似滚动停靠)
2013/03/27 Javascript
js 输出内容到新窗口具体实现代码
2013/05/31 Javascript
js获取URL的参数的方法(getQueryString)示例
2013/09/29 Javascript
在Google 地图上实现做的标记相连接
2015/01/05 Javascript
Vue.js每天必学之Class与样式绑定
2016/09/05 Javascript
jQuery实现弹出窗口弹出div层的实例代码
2017/01/09 Javascript
JS中正则表达式全局匹配模式 /g用法详解
2017/04/01 Javascript
Google 爬虫如何抓取 JavaScript 的内容
2017/04/07 Javascript
jQuery简单绑定单个事件的方法示例
2017/06/10 jQuery
vue实现表格增删改查效果的实例代码
2017/07/18 Javascript
基于js文件加载优化(详解)
2018/01/03 Javascript
layui实现table加载的示例代码
2018/08/14 Javascript
新手必须知的Node.js 4个JavaScript基本概念
2018/09/16 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
浅谈Vue为什么不能检测数组变动
2019/10/14 Javascript
python格式化字符串实例总结
2014/09/28 Python
python 插入日期数据到Oracle实例
2020/03/02 Python
Python decimal模块使用方法详解
2020/06/08 Python
Python存储读取HDF5文件代码解析
2020/11/25 Python
详解如何解决使用JSON.stringify时遇到的循环引用问题
2021/03/23 Javascript
大学生入党思想汇报
2014/01/01 职场文书
社区工作者演讲稿
2014/05/23 职场文书
天地会口号
2014/06/17 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
党的群众路线调研报告
2014/11/03 职场文书
滴水洞导游词
2015/02/10 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
2015年服务员工作总结
2015/04/08 职场文书
《认识年月日》教学反思
2016/02/19 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫
使用CSS实现音波加载效果
2023/05/07 HTML / CSS