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分析apache访问日志脚本分享
Feb 26 Python
Python闭包实现计数器的方法
May 05 Python
使用Python发送各种形式的邮件的方法汇总
Nov 09 Python
python 迭代器和iter()函数详解及实例
Mar 21 Python
浅谈Python生成器generator之next和send的运行流程(详解)
May 08 Python
十分钟利用Python制作属于你自己的个性logo
May 07 Python
python利用跳板机ssh远程连接redis的方法
Feb 19 Python
Python简直是万能的,这5大主要用途你一定要知道!(推荐)
Apr 03 Python
python导包的几种方法(自定义包的生成以及导入详解)
Jul 15 Python
Python队列RabbitMQ 使用方法实例记录
Aug 05 Python
基于Tensorflow使用CPU而不用GPU问题的解决
Feb 07 Python
装上这 14 个插件后,PyCharm 真的是无敌的存在
Jan 11 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下的权限算法的实现
2007/04/28 PHP
php后台多用户权限组思路与实现程序代码分享
2012/02/13 PHP
验证token、回复图文\文本、推送消息的实用微信类php代码
2016/06/28 PHP
PHP 中TP5 Request 请求对象的实例详解
2017/07/31 PHP
CSS+JS构建的图片查看器
2006/07/22 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
js网页实时倒计时精确到秒级
2014/02/10 Javascript
JS实现跟随鼠标闪烁转动色块的方法
2015/02/26 Javascript
JavaScript中的函数嵌套使用
2015/06/04 Javascript
使用jQuery监听DOM元素大小变化
2016/02/24 Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
2016/09/08 Javascript
js数组与字符串常用方法总结
2017/01/13 Javascript
requirejs + vue 项目搭建详解
2017/06/16 Javascript
详解如何使用webpack+es6开发angular1.x
2017/08/16 Javascript
Bootstrap 模态框(Modal)带参数传值实例
2017/08/20 Javascript
详解bootstrap用dropdown-menu实现上下文菜单
2017/09/22 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
浅谈layui框架自带分页和表格重载的接口解析问题
2019/09/11 Javascript
Python使用设计模式中的责任链模式与迭代器模式的示例
2016/03/02 Python
python对excel文档去重及求和的实例
2018/04/18 Python
代码详解django中数据库设置
2019/01/28 Python
Django打印出在数据库中执行的语句问题
2019/07/25 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
keras实现theano和tensorflow训练的模型相互转换
2020/06/19 Python
分享CSS3制作卡片式图片的方法
2016/07/08 HTML / CSS
白兰氏健康Mall:BRAND’S
2017/11/13 全球购物
优衣库美国官网:UNIQLO美国
2018/04/14 全球购物
Chinti & Parker官网:奢华羊绒女装和创新针织设计
2021/01/01 全球购物
Ado与Ado.net的相同与不同
2014/12/08 面试题
异步传递消息系统的作用
2016/05/01 面试题
幼师岗位求职简历的自荐信格式
2013/09/21 职场文书
毕业生个人的求职信范文
2013/12/03 职场文书
中学教师教育感言
2014/02/21 职场文书
公司开业庆典主持词
2014/03/21 职场文书
PHP控制循环操作的时间
2021/04/01 PHP