Python中Django发送带图片和附件的邮件


Posted in Python onMarch 31, 2017

最近需要做集团的SRC系统。暂无安全研发,所以只能找我这个小菜兼职开发。系统使用Django框架,在整个过程中,有许多奇特的需求。在某项需求中,需要给厂商用户发送富文本邮件,漏洞详情,这个折腾了一下,感觉略有收获,所以记一篇随笔。

首先我在网上搜索了一些资料,发现都是python通过smtplib发送,使用MIME格式来生成富文本邮件:传送门

我想的是,使用Django框架,框架带了邮件模块,没必要引入smtplib吧。我就想,向上文传送门那样,生成一个MIME文件,然后通过

from django.core import mail
 mail.send_mail

这种方式把MIMEMultipart对象使用as_string()方法生成的文件当做message发出去不就好了吗。呃,有兴趣的可以试一下。。我发出去了一堆字符串。。

好吧,失败了,难道真的要把smtplib引进来?

天无绝人之路,这个时候我看到了一句话:EmailMessage是Django封装好的smtp。哦?还有这回事?好吧,尝试一下看看源码?跳转至message.py

class EmailMessage(object):
  """
  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):
    """
    Initialize a single email message (which can be sent to multiple
    recipients).

    All strings used to create the message can be unicode strings
    (or UTF-8 bytestrings). The SafeMIMEText class will handle any
    necessary encoding conversions.
    """

恩!大体知道了用法。

msg = mail.EmailMessage('富文本邮件测试', html, from_mail, recipient_list)

就是这样了。而且看message.py文件

if to:
       if isinstance(to, six.string_types):
        raise TypeError('"to" argument must be a list or tuple')
      self.to = list(to)

看到raise的信息,明白了,我们传给他的recipient_list应该是元组或者列表

self.from_email = from_email or settings.DEFAULT_FROM_EMAIL

我们传给他的就是Django settings.py文件里配置的邮箱,就是以下格式的:

# email config
# 这是我们工程目录下settings文件的配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_HOST_PASSWORD = 'xxxxxxxx'
EMAIL_HOST_USER = 'xxxx@xxxx.xxxx'
EMAIL_HOST = 'smtp.xxxx.com'
EMAIL_PORT = port

好,到此为止,我们知道了这个类怎么用。我们看传送门里的代码,挑选比较重要的

msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = subject
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgText = MIMEText(plainText, 'plain', 'utf-8')
msgAlternative.attach(msgText)

#设定HTML信息
msgText = MIMEText(htmlText, 'html', 'utf-8')
msgAlternative.attach(msgText)

然后我们对比一下message.py里面的代码:

def message(self):
    encoding = self.encoding or settings.DEFAULT_CHARSET
    msg = SafeMIMEText(self.body, self.content_subtype, encoding)
    msg = self._create_message(msg)
    msg['Subject'] = self.subject
    msg['From'] = self.extra_headers.get('From', self.from_email)
    msg['To'] = self.extra_headers.get('To', ', '.join(map(force_text, self.to)))

篇幅所限不粘贴太多,有兴趣可以自己去研读。我们发现,他们是不是很像,其实读完整个message.py我们会发现一件事。原来EmailMessage这个类的对象,可以看做是MIMEMultipart对象加上了smtplib的发送功能。而且它也有attach方法,可以像MIMEMultipart对象那样拼接富文本邮件内容,好,这就有办法了!我们通过EmailMessage来发送富文本邮件!

# -*- coding: utf-8 -*-
# ===============================================================================
# @ Creator:首席小学生
# @ Date:2017-03-28
# 构造富文本邮件内容
# ===============================================================================
import os
from email.mime.image import MIMEImage
from django.conf import settings
from django.core import mail


def add_img(src, img_id):
  """
  在富文本邮件模板里添加图片
  :param src:
  :param img_id:
  :return:
  """
  fp = open(src, 'rb')
  msg_image = MIMEImage(fp.read())
  fp.close()
  msg_image.add_header('Content-ID', '<'+img_id+'>')
  return msg_image


def send_util():
  path = os.getcwd()
  path_use = path.replace('\\', '/')
  html = '''
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
  </head>
  <body>
  牛逼呀小伙子,你成功了
  <img src="cid:test_cid"/>
  </body>
  </html>
  '''
  recipient_list = ['xxxx@xxxx.com']
  from_mail = settings.EMAIL_HOST_USER
  msg = mail.EmailMessage('富文本邮件测试', html, from_mail, recipient_list)
  msg.content_subtype = 'html'
  msg.encoding = 'utf-8'
  image = add_img(path_use+'/mail_util/test.png', 'test_cid')
  msg.attach(image)
  if msg.send():
    return True
  else:
    return False

我们在views中设置视图函数,调用上面这些测试方法尝试一下:

from django.shortcuts import render
from html_to_mail import send_util


def send_mail(request):
  if send_util():
    return render(request, 'ok.html')
  else:
    return render(request, 'error.html')

在urls里面随意配置一个映射指向这个视图函数,把Django工程run起来,直接在浏览器get这个映射。发现邮件发送成功!

Python中Django发送带图片和附件的邮件

工程目录如上图。我不想上传代码,我觉得直接下载源码用来用的话很难学会

 就是这样,我完成了Django的富文本邮件发送。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
关于你不想知道的所有Python3 unicode特性
Nov 28 Python
Python浅拷贝与深拷贝用法实例
May 09 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
Jan 09 Python
Python中的Django基本命令实例详解
Jul 15 Python
Python绘制并保存指定大小图像的方法
Jan 10 Python
Python玩转Excel的读写改实例
Feb 22 Python
Python中使用遍历在列表中添加字典遇到的坑
Feb 27 Python
linux中如何使用python3获取ip地址
Jul 15 Python
python文件操作的简单方法总结
Nov 07 Python
django 模型中的计算字段实例
May 19 Python
使用Python实现NBA球员数据查询小程序功能
Nov 09 Python
Pycharm在指定目录下生成文件和删除文件的实现
Dec 28 Python
使用Python对Access读写操作
Mar 30 #Python
使用Python对Excel进行读写操作
Mar 30 #Python
浅述python中argsort()函数的实例用法
Mar 30 #Python
Windows下安装python2和python3多版本教程
Mar 30 #Python
详解Python之数据序列化(json、pickle、shelve)
Mar 30 #Python
python类的继承实例详解
Mar 30 #Python
django轻松使用富文本编辑器CKEditor的方法
Mar 30 #Python
You might like
PHP生成不同颜色、不同大小的tag标签函数
2013/09/23 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
JavaScript 全角转半角部分
2009/10/28 Javascript
从零开始学习jQuery (十) jQueryUI常用功能实战
2011/02/23 Javascript
基于jquery的设置页面文本框 只能输入数字的实现代码
2011/04/19 Javascript
基于jquery的图片轮播 tab切换组件
2012/07/19 Javascript
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
js添加select下默认的option的value和text的方法
2014/10/19 Javascript
JavaScript实现带箭头标识的多级下拉菜单效果
2015/08/27 Javascript
AngularJS 单元测试(一)详解
2016/09/21 Javascript
jQuery插件实现可输入和自动匹配的下拉框
2016/10/24 Javascript
微信小程序 开发之快递查询功能的实现
2017/01/09 Javascript
js判断传入时间和当前时间大小实例(超简单)
2018/01/11 Javascript
node内置调试方法总结
2018/02/22 Javascript
JavaScript变速动画函数封装添加任意多个属性
2019/04/03 Javascript
浅谈element中InfiniteScroll按需引入的一点注意事项
2020/06/05 Javascript
[39:53]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.19
2020/11/19 DOTA
python2 与 python3 实现共存的方法
2018/07/12 Python
浅析python中numpy包中的argsort函数的使用
2018/08/30 Python
python最小生成树kruskal与prim算法详解
2019/01/17 Python
python将视频转换为全字符视频
2019/04/26 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
pycharm激活码有效到2020年11月底
2020/09/18 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
印度购物网站:TATA CLiQ
2017/11/23 全球购物
11月升旗仪式讲话稿
2014/02/15 职场文书
行政助理工作职责范本
2014/03/04 职场文书
学生请假条
2014/04/11 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
售房委托书
2014/08/30 职场文书
党员学习中共十八大报告思想汇报
2014/09/15 职场文书
给下属加薪申请报告
2015/05/15 职场文书
2016天猫双十一广告语
2016/01/28 职场文书
pytorch加载预训练模型与自己模型不匹配的解决方案
2021/05/13 Python
spring cloud 配置中心客户端启动遇到的问题
2021/09/25 Java/Android
Nginx实现负载均衡的项目实践
2022/03/18 Servers