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 相关文章推荐
python网络编程之读取网站根目录实例
Sep 30 Python
python编程开发之日期操作实例分析
Nov 13 Python
Pythont特殊语法filter,map,reduce,apply使用方法
Feb 27 Python
Python实现的视频播放器功能完整示例
Feb 01 Python
Python错误处理操作示例
Jul 18 Python
Python设计模式之命令模式原理与用法实例分析
Jan 11 Python
pytorch 加载(.pth)格式的模型实例
Aug 20 Python
python 比较字典value的最大值的几种方法
Apr 17 Python
Python ADF 单位根检验 如何查看结果的实现
Jun 03 Python
python 字符串的驻留机制及优缺点
Jun 19 Python
python raise的基本使用
Sep 10 Python
Python爬虫之App爬虫视频下载的实现
Dec 08 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 setcookie指定domain参数后,在IE下设置cookie失效的解决方法
2011/09/09 PHP
PHP代码实现爬虫记录――超管用
2015/07/31 PHP
yii2.0整合阿里云oss上传单个文件的示例
2017/09/19 PHP
jQuery 图像裁剪插件Jcrop的简单使用
2009/05/22 Javascript
使用javascript实现有效时间的控制,并显示将要过期的时间
2014/01/02 Javascript
javascript遍历控件实例详细解析
2014/01/10 Javascript
jQuery实现精美的多级下拉菜单特效
2015/03/14 Javascript
jquery选择器简述
2015/08/31 Javascript
利用angularjs1.4制作的简易滑动门效果
2017/02/28 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
如何在Vue.js中实现标签页组件详解
2019/01/02 Javascript
基于vue实现图片验证码倒计时60s功能
2019/12/10 Javascript
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
2020/07/22 Javascript
[03:36]2014DOTA2 TI小组赛综述 八强诞生进军钥匙球馆
2014/07/15 DOTA
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
Python里隐藏的“禅”
2014/06/16 Python
详解Python中dict与set的使用
2015/08/10 Python
Python 登录网站详解及实例
2017/04/11 Python
python中的内置函数max()和min()及mas()函数的高级用法
2018/03/29 Python
使用Python通过win32 COM打开Excel并添加Sheet的方法
2018/05/02 Python
Django rest framework实现分页的示例
2018/05/24 Python
Pandas 按索引合并数据集的方法
2018/11/15 Python
python程序变成软件的实操方法
2019/06/24 Python
用vue.js组件模拟v-model指令实例方法
2019/07/05 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
2019/09/07 Python
python3读取csv文件任意行列代码实例
2020/01/13 Python
让IE可以变相支持CSS3选择器
2010/01/21 HTML / CSS
使用 css3 实现圆形进度条的示例
2017/07/05 HTML / CSS
HTML5实现移动端点击翻牌功能
2020/10/23 HTML / CSS
北美主要的汽车零部件零售商:AutoShack.com
2019/02/23 全球购物
市场部规章制度
2014/01/24 职场文书
五四青年节的活动方案
2014/08/20 职场文书
个人买房协议书范本
2014/10/06 职场文书
小学安全教育主题班会
2015/08/12 职场文书
解决hive中导入text文件遇到的坑
2021/04/07 Python
Jedis操作Redis实现模拟验证码发送功能
2021/09/25 Redis