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 19 Python
Python 基础教程之包和类的用法
Feb 23 Python
python 性能优化方法小结
Mar 31 Python
Python 通过pip安装Django详细介绍
Apr 28 Python
Python之批量创建文件的实例讲解
May 10 Python
解决Python3.5+OpenCV3.2读取图像的问题
Dec 05 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
Jun 26 Python
pandas将多个dataframe以多个sheet的形式保存到一个excel文件中
Oct 10 Python
Python中的 ansible 动态Inventory 脚本
Jan 19 Python
如何验证python安装成功
Jul 06 Python
python 如何对logging日志封装
Dec 02 Python
详解非极大值抑制算法之Python实现
Jun 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
英雄试炼之肉山谷—引领RPG新潮流
2020/04/20 DOTA
把PHP安装为Apache DSO
2006/10/09 PHP
php字符串分割函数explode的实例代码
2013/02/07 PHP
yii2 上传图片的示例代码
2018/11/02 PHP
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
JS之Date对象和获取系统当前时间详解
2014/01/13 Javascript
javascript+css3 实现动态按钮菜单特效
2016/02/06 Javascript
Javascript基础学习笔记(菜鸟必看篇)
2016/07/22 Javascript
基于bootstrap实现广告轮播带图片和文字效果
2016/07/22 Javascript
关于Promise 异步编程的实例讲解
2017/09/01 Javascript
JS库 Highlightjs 添加代码行号的实现代码
2017/09/13 Javascript
vuex 使用文档小结篇
2018/01/11 Javascript
JavaScript判断浏览器运行环境的详细方法
2019/06/30 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
2020/01/21 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
2020/02/05 Javascript
JavaScript编写开发动态时钟
2020/07/29 Javascript
浅谈vue中get请求解决传输数据是数组格式的问题
2020/08/03 Javascript
DJANGO-ALLAUTH社交用户系统的安装配置
2014/11/18 Python
Python的Django REST框架中的序列化及请求和返回
2016/04/11 Python
Django contenttypes 框架详解(小结)
2018/08/13 Python
Django 过滤器汇总及自定义过滤器使用详解
2019/07/19 Python
Python cookie的保存与读取、SSL讲解
2020/02/17 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
Python浮点型(float)运算结果不正确的解决方案
2020/09/22 Python
RentCars.com巴西:汽车租赁网站
2016/08/22 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
环境科学专业大学生自荐信格式
2013/09/21 职场文书
工作中的自我评价如何写好
2013/10/28 职场文书
2014领导班子四风问题查摆思想汇报
2014/09/13 职场文书
小学语文课《掌声》教学反思
2016/03/03 职场文书
新员工入职感言范文!
2019/07/04 职场文书
文艺有韵味的诗句(生命类、亲情类...)
2019/07/11 职场文书
Python Django搭建文件下载服务器的实现
2021/05/10 Python
springboot 启动如何排除某些bean的注入
2021/08/02 Java/Android