django基础学习之send_mail功能


Posted in Python onAugust 07, 2019

前言

我们知道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 相关文章推荐
Django1.3添加app提示模块不存在的解决方法
Aug 26 Python
在Python中编写数据库模块的教程
Apr 29 Python
Pthon批量处理将pdb文件生成dssp文件
Jun 21 Python
Django框架中数据的连锁查询和限制返回数据的方法
Jul 17 Python
使用python实现rsa算法代码
Feb 17 Python
python常用函数详解
Sep 13 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
Jun 19 Python
Django中celery执行任务结果的保存方法
Jul 12 Python
Python加密模块的hashlib,hmac模块使用解析
Jan 02 Python
TensorFlow2.X使用图片制作简单的数据集训练模型
Apr 08 Python
Pycharm如何自动生成头文件注释
Nov 14 Python
Python常用配置文件ini、json、yaml读写总结
Jul 09 Python
python实现本地批量ping多个IP的方法示例
Aug 07 #Python
Django model 中设置联合约束和联合索引的方法
Aug 06 #Python
对django 模型 unique together的示例讲解
Aug 06 #Python
python django model联合主键的例子
Aug 06 #Python
django多文件上传,form提交,多对多外键保存的实例
Aug 06 #Python
详解python中的index函数用法
Aug 06 #Python
详解python 利用echarts画地图(热力图)(世界地图,省市地图,区县地图)
Aug 06 #Python
You might like
php设计模式 Mediator (中介者模式)
2011/06/26 PHP
PHP基于imap获取邮件实例
2014/11/11 PHP
关于使用runtimeStyle属性问题讨论文章
2007/03/08 Javascript
JQuery for与each性能比较分析
2013/05/14 Javascript
IE下写xml文件的两种方式(fso/saveAs)
2013/08/05 Javascript
jquery-syntax动态语法着色示例代码
2014/05/14 Javascript
IE8下Jquery获取select选中的值post到后台报错问题
2014/07/02 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
2016/03/17 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
用js屏蔽被http劫持的浮动广告实现方法
2017/08/10 Javascript
JS switch判断 三目运算 while 及 属性操作代码
2017/09/03 Javascript
Vue服务器渲染Nuxt学习笔记
2018/01/31 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
2019/05/17 jQuery
JavaScript提升机制Hoisting详解
2019/10/23 Javascript
解决Echarts2竖直datazoom滑动后显示数据不全的问题
2020/07/20 Javascript
[01:21]辉夜杯战队访谈宣传片—CDEC
2015/12/25 DOTA
[01:21]DOTA2新纪元-7.0新版本即将开启!
2016/12/11 DOTA
[02:16]深扒TI7聊天轮盘语音出处2
2017/05/11 DOTA
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Django应用程序中如何发送电子邮件详解
2017/02/04 Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
2017/12/19 Python
50行Python代码实现人脸检测功能
2018/01/23 Python
python 读写excel文件操作示例【附源码下载】
2019/06/19 Python
Python产生一个数值范围内的不重复的随机数的实现方法
2019/08/21 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
2020/03/10 Python
使用Dajngo 通过代码添加xadmin用户和权限(组)
2020/07/03 Python
css3实现顶部社会化分享按钮示例
2014/05/06 HTML / CSS
女士和男士时尚鞋在线购物:Shoespie
2019/02/28 全球购物
英国钻石公司:British Diamond Company
2020/02/16 全球购物
三星加拿大官方网上商店:Samsung CA
2020/12/18 全球购物
公司贷款承诺书
2014/05/30 职场文书
2015年文明创建工作总结
2015/04/30 职场文书
Python Numpy之linspace用法说明
2021/04/17 Python
golang判断key是否在map中的代码
2021/04/24 Golang
JAVA 线程池(池化技术)的实现原理
2022/04/28 Java/Android