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学习之第三方包安装方法(两种方法)
Jul 30 Python
Python中在for循环中嵌套使用if和else语句的技巧
Jun 20 Python
Python使用MD5加密算法对字符串进行加密操作示例
Mar 30 Python
PyQt5每天必学之拖放事件
Aug 27 Python
python调用摄像头拍摄数据集
Jun 01 Python
Python2和3字符编码的区别知识点整理
Aug 08 Python
python-docx文件定位读取过程(尝试替换)
Feb 13 Python
基于python实现破解滑动验证码过程解析
May 28 Python
python3获取控制台输入的数据的具体实例
Aug 16 Python
多个版本的python共存时使用pip的正确做法
Oct 26 Python
django中ImageField的使用详解
Dec 21 Python
Python的信号库Blinker用法详解
Dec 31 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 抽象类的简单应用
2011/09/06 PHP
php stripslashes和addslashes的区别
2014/02/03 PHP
浅谈php安全性需要注意的几点事项
2014/07/17 PHP
php实现无限级分类查询(递归、非递归)
2016/03/10 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
2016/09/23 PHP
php版微信js-sdk支付接口类用法示例
2016/10/12 PHP
Zend Framework动作控制器用法示例
2016/12/09 PHP
javascript之ESC(第二类混淆)
2007/05/06 Javascript
细品javascript 寻址,闭包,对象模型和相关问题
2009/04/27 Javascript
超越Jquery_01_isPlainObject分析与重构
2010/10/20 Javascript
javascript和HTML5利用canvas构建猜牌游戏实现算法
2013/07/17 Javascript
jquery实现勾选复选框触发事件给input赋值
2015/02/01 Javascript
javascript中createElement的两种创建方式
2015/05/14 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
Bootstrap每天必学之栅格系统(布局)
2015/11/25 Javascript
由浅入深剖析Angular表单验证
2016/07/14 Javascript
javascript内存分配原理实例分析
2017/04/10 Javascript
react.js 获取真实的DOM节点实例(必看)
2017/04/17 Javascript
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
详解服务端预渲染之Nuxt(介绍篇)
2019/04/07 Javascript
jquery3和layui冲突导致使用layui.layer.full弹出全屏iframe窗口时高度152px问题
2019/05/12 jQuery
vue-列表下详情的展开与折叠案例
2020/07/28 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
python3学习笔记之多进程分布式小例子
2018/02/13 Python
python 删除字符串中连续多个空格并保留一个的方法
2018/12/22 Python
pycharm访问mysql数据库的方法步骤
2019/06/18 Python
django获取from表单multiple-select的value和id的方法
2019/07/19 Python
python打包多类型文件的操作方法
2020/09/21 Python
整理HTML5的一些新特性与Canvas的常用属性
2016/01/29 HTML / CSS
2013年保送生自荐信格式
2013/11/20 职场文书
派出所所长先进事迹
2014/05/19 职场文书
餐厅服务员岗位职责
2015/02/09 职场文书
工作态度恶劣检讨书
2015/05/06 职场文书
《伯牙绝弦》教学反思
2016/02/16 职场文书
《地。-关于地球的运动-》单行本第七集上市,小说家朝井辽献上期待又害怕的推荐文
2022/03/31 日漫