zoukankan      html  css  js  c++  java
  • Django发送带图片和附件的邮件

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

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

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

      

    1 from django.core import mail
    2 mail.send_mail

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

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

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

     1 class EmailMessage(object):
     2     """
     3     A container for email information.
     4     """
     5     content_subtype = 'plain'
     6     mixed_subtype = 'mixed'
     7     encoding = None     # None => use settings default
     8 
     9     def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
    10                  connection=None, attachments=None, headers=None, cc=None,
    11                  reply_to=None):
    12         """
    13         Initialize a single email message (which can be sent to multiple
    14         recipients).
    15 
    16         All strings used to create the message can be unicode strings
    17         (or UTF-8 bytestrings). The SafeMIMEText class will handle any
    18         necessary encoding conversions.
    19         """

      恩!大体知道了用法。

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

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

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

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

    self.from_email = from_email or settings.DEFAULT_FROM_EMAIL

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

    1 # email config
    2 # 这是我们工程目录下settings文件的配置
    3 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    4 
    5 EMAIL_HOST_PASSWORD = 'xxxxxxxx'
    6 EMAIL_HOST_USER = 'xxxx@xxxx.xxxx'
    7 EMAIL_HOST = 'smtp.xxxx.com'
    8 EMAIL_PORT = port

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

     1 msgRoot = MIMEMultipart('related')
     2 msgRoot['Subject'] = subject
     3 msgRoot['From'] = strFrom
     4 msgRoot['To'] = strTo
     5 msgText = MIMEText(plainText, 'plain', 'utf-8')
     6 msgAlternative.attach(msgText)
     7 
     8 #设定HTML信息
     9 msgText = MIMEText(htmlText, 'html', 'utf-8')
    10 msgAlternative.attach(msgText)

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

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

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

     1 # -*- coding: utf-8 -*-
     2 # ===============================================================================
     3 # @ Creator:首席小学生
     4 # @ Date:2017-03-28
     5 # 构造富文本邮件内容
     6 # ===============================================================================
     7 import os
     8 from email.mime.image import MIMEImage
     9 from django.conf import settings
    10 from django.core import mail
    11 
    12 
    13 def add_img(src, img_id):
    14     """
    15     在富文本邮件模板里添加图片
    16     :param src:
    17     :param img_id:
    18     :return:
    19     """
    20     fp = open(src, 'rb')
    21     msg_image = MIMEImage(fp.read())
    22     fp.close()
    23     msg_image.add_header('Content-ID', '<'+img_id+'>')
    24     return msg_image
    25 
    26 
    27 def send_util():
    28     path = os.getcwd()
    29     path_use = path.replace('\', '/')
    30     html = '''
    31     <!DOCTYPE html>
    32     <html lang="en">
    33     <head>
    34         <meta charset="UTF-8">
    35         <title>Title</title>
    36     </head>
    37     <body>
    38     牛逼呀小伙子,你成功了
    39     <img src="cid:test_cid"/>
    40     </body>
    41     </html>
    42     '''
    43     recipient_list = ['xxxx@xxxx.com']
    44     from_mail = settings.EMAIL_HOST_USER
    45     msg = mail.EmailMessage('富文本邮件测试', html, from_mail, recipient_list)
    46     msg.content_subtype = 'html'
    47     msg.encoding = 'utf-8'
    48     image = add_img(path_use+'/mail_util/test.png', 'test_cid')
    49     msg.attach(image)
    50     if msg.send():
    51         return True
    52     else:
    53         return False

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

    1 from django.shortcuts import render
    2 from html_to_mail import send_util
    3 
    4 
    5 def send_mail(request):
    6     if send_util():
    7         return render(request, 'ok.html')
    8     else:
    9         return render(request, 'error.html')

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

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

    就是这样,我完成了Django的富文本邮件发送。毕竟是兼职开发,哪里有问题的话,欢迎各位前辈不吝赐教,谢谢。

  • 相关阅读:
    AutoCAD利用VBA设置线型和添加用户自定义线性
    AutoVBA利用for循环创建同心圆弧
    AutoVBA利用Hacth对象填充图元对象
    AutoVBA利用AddArc方法创建Arc对象
    2011年6月5日星期天
    AutoVBA控件的tabindex和tabstop属性及with语句
    AutoVBA在绘图空间创建直线对象
    AutoVBA利用toolbar创建自己的工具栏
    AutoVBA调用AddCricle方法绘制圆
    AutoCAD利用VBA宏绘制多重平行线
  • 原文地址:https://www.cnblogs.com/hainan-zhang/p/6647980.html
Copyright © 2011-2022 走看看