前言

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

python测试开发django-30.发送附件EmailMessage的更多相关文章

  1. python测试开发django-50.jquery发送ajax请求(get)

    前言 有时候,我们希望点击页面上的某个按钮后,不刷新整个页面,给后台发送一个请求过去,请求到数据后填充到html上,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新.Ajax可以完美的 ...

  2. python测试开发django-51.Ajax发送post请求登录案例

    前言 我想实现一个登录功能:登录的接口是另外一个地方提供,页面上点登录按钮的时候,先访问登录接口,根据接口返回json信息判断是否登录成功,登录成功页面跳转,登录不成功,在登录首页显示失败原因 登录页 ...

  3. python测试开发django-36.一对一(OneToOneField)关系查询

    前言 前面一篇在xadmin后台一个页面显示2个关联表(OneToOneField)的字段,使用inlines内联显示.本篇继续学习一对一(OneToOneField)关系的查询. 上一篇list_d ...

  4. 2019第一期《python测试开发》课程,10月13号开学

    2019第一期<python测试开发>课程,10月13号开学! 主讲老师:上海-悠悠 上课方式:QQ群视频在线教学,方便交流 本期上课时间:10月13号-12月8号,每周六.周日晚上20: ...

  5. python测试开发django-rest-framework-63.基于函数的视图(@api_view())

    前言 上一篇讲了基于类的视图,在REST framework中,你也可以使用常规的基于函数的视图.它提供了一组简单的装饰器,用来包装你的视图函数, 以确保视图函数会收到Request(而不是Djang ...

  6. python测试开发django-16.JsonResponse返回中文编码问题

    前言 django查询到的结果,用JsonResponse返回在页面上显示类似于\u4e2d\u6587 ,注意这个不叫乱码,这个是unicode编码,python3默认返回的编码 遇到问题 接着前面 ...

  7. python测试开发django-15.查询结果转json(serializers)

    前言 django查询数据库返回的是可迭代的queryset序列,如果不太习惯这种数据的话,可以用serializers方法转成json数据,更直观 返回json数据,需要用到JsonResponse ...

  8. 《Python测试开发技术栈—巴哥职场进化记》—前言

    写在前面 今年从4月份开始写一本讲Python测试开发技术栈的书,主要有两个目的,第一是将自己掌握的一些内容分享给大家,第二是希望自己能系统的梳理和学习Python相关的技术栈.当时我本来打算以故事体 ...

  9. 《Python测试开发技术栈—巴哥职场进化记》—初来乍到,请多关照

    上文<巴哥职场进化记-Python测试开发技术栈>开篇讲到巴哥毕业初到深圳,见到了来自五湖四海的室友.一番畅聊之后,抱着对未来职场生活的期待,大家都进入了梦乡.今天我们来看看巴哥第一天上班 ...

  10. 《Python测试开发技术栈—巴哥职场进化记》—软件测试工程师“兵器库”

    上文<Python测试开发技术栈-巴哥职场进化记>-初来乍到,请多关照 我们介绍了巴哥入职后见到了自己的导师华哥,第一次参加团队站会,认识了团队中的开发小哥哥和产品小姐姐以及吃到了公司的加 ...

随机推荐

  1. POJ 3281 Dining(最大流+拆点)

    题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...

  2. 2018-2019-2 网络对抗技术 20165301 Exp2 后门原理与实践

    2018-2019-2 网络对抗技术 20165301 Exp2 后门原理与实践 实验内容 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任 ...

  3. JS模块化编程(二):require.js基本用法

    require.config() 接受一个配置对象 常用属性: paths: shim: 配置不兼容的模块 baseUrl: 引用模块的文件基目录

  4. .NetCore下使用Prometheus实现系统监控和警报 (二)Linux安装

    Prometheus对Windows有相关的支持  下载地址:https://prometheus.io/download/ wget https://github.com/prometheus/pr ...

  5. JS的异步模式

    JS的异步模式:1.回调函数:2.事件监听:3.观察者模式:4.promise对象 JavaScript语言将任务的执行模式可以分成两种:同步(Synchronous)和异步(Asychronous) ...

  6. 【LOJ】#2122. 「HEOI2015」小 Z 的房间

    题解 又是一道取模不给质数的毒瘤矩阵树题 不会写分数类--然后发现了网上过于神仙的题解类似与辗转相除的这样把某一个位置消成0 orz 代码 #include <bits/stdc++.h> ...

  7. 关于调用&&传址

    关于调用&&传址//数组int d1[];Function(int *d){} int main(){Function(d1);} //指针int *p;Function(int *q ...

  8. 重写(Override) 重载(Overload)

    重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重载(Overload)- 参数必须不同 重载(overloadin ...

  9. 使用Synchronized关键字同步类方法

    要想解决“脏数据”的问题,最简单的方法就是使用synchronized关键字来使run方法同步,代码如下: public synchronized void run() { } 从上面的代码可以看出, ...

  10. HDU.5181.numbers(DP)

    题目链接 参考. \(Description\) 将\(1,2,\cdots,n(n\leq 300)\)依次入栈/出栈,并满足\(m(m\leq 90000)\)个形如\(x\)要在\(y\)之前出 ...