django中多线程发送邮件

版权声明:本文系作者原创。未经许可,不得转载。

    
    在django中发送邮件,可以使用python原生的smtplib模块,也可以使用django封装过的django.core.mail模块。使用多线程,发送邮件不阻塞主线程。分别举例如下:

一、使用smtplib模块
    
    <send_email_thread.py>

    #!/usr/bin/env python2.7.3

__author__ = 'simba'
#coding: utf-8

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.header import Header
from config import UserName, Password, SmtpServer, EmailAddress, SmtpPort, UseTLS
from app_store.settings import DEBUG
import os
import email.MIMEBase
from time import sleep
import threading


class SendEmailThread(threading.Thread):
    def __init__(self):
        super(SendEmailThread, self).__init__()
        self.__smtpserver = SmtpServer
        self.__smtpport = SmtpPort
        self.__username = UserName
        self.__password = Password
        self.__sender = EmailAddress
        # Create message container - the correct MIME type is multipart/alternative.
        self.__msg = MIMEMultipart('alternative')
        self.__msg['Date'] = email.Utils.formatdate()

    #主题
    def set_subject(self, subject):
        header = Header(subject, 'utf-8')
        self.__msg['Subject'] = header

    #收件人
    def set_receiver(self, receiver_list):
        if not type(receiver_list) == list:  #收件人必须为链表
            raise ValueError, 'Invalid Argument'
        self.__msg['To'] = ";".join(receiver_list)  #这句话必须有, 此乃smtplib的bug.
        self.__receiver = receiver_list

    #发件人
    def set_sender(self, sender=u'XX科技'):
        self.__msg['From'] = sender

    #文本
    def set_text(self, text=u'这是一封来自XX科技的系统邮件,请勿回复!'):
        # Record the MIME type - text/plain
        text_part = MIMEText(text, 'plain', 'utf-8')
        # Attach parts into message container
        self.__msg.attach(text_part)

    #网页
    def set_html(self, html):
        # Record the MIME type - text/html
        html_part = MIMEText(html, 'html', 'utf-8')
        # Attach parts into message container
        self.__msg.attach(html_part)

    #图片
    def set_image(self, image_path, image_name=None):
        image = '<img src="cid:image">'
        # Record the MIME type- text/html
        image_part = MIMEText(image, 'html', 'utf-8')
        self.__msg.attach(image_part)
        fp = open(image_path, 'rb')
        msgImage = MIMEImage(fp.read())
        fp.close()
        msgImage.add_header('Content-ID', '<image>')
        if not image_name:
            image_name = os.path.basename(image_path)
        msgImage["Content-Disposition"] = 'attachment; filename=' + image_name
        self.__msg.attach(msgImage)

    #附件
    def set_file(self, file_path, file_name=None):
        if not file_name:
            file_name = os.path.basename(file_path)

        # 构造MIMEBase对象做为文件附件内容并附加到根容器
        contype = 'application/octet-stream'
        maintype, subtype = contype.split('/', 1)

        ## 读入文件内容并格式化
        data = open(file_path, 'rb')
        file_msg = email.MIMEBase.MIMEBase(maintype, subtype)
        file_msg.set_payload(data.read(), charset='utf-8')
        data.close( )
        email.Encoders.encode_base64(file_msg)#把附件编码

        ## 设置附件头
        file_msg.add_header('Content-Disposition','attachment', filename = file_name)#修改邮件头
        self.__msg.attach(file_msg)

    #发送邮件
    def run(self):
        try:
            if UseTLS:
                smtp = smtplib.SMTP() #587端口和TLS链接
            else:
                smtp = smtplib.SMTP_SSL()  #465端口和SSL链接
            smtp.connect(self.__smtpserver, self.__smtpport)
            if UseTLS:  #587端口和TLS链接
                smtp.ehlo()
                smtp.starttls()
                smtp.ehlo()
            smtp.set_debuglevel(DEBUG)   #根据settings.py中的DEBUG值设置是否打印调试信息
            smtp.login(self.__username, self.__password)
            smtp.sendmail(self.__sender, self.__receiver, self.__msg.as_string())
            sleep(5)                          #避免邮件没有发送完成就调用了quit()
            smtp.quit()
            return True
        except Exception, e:
            return False


<send_email_register.py>

#!/usr/bin/env python2.7.3

__author__ = 'simba'
# -*- coding: utf-8 -*-

from send_email_thread import SendEmailThread
import os
from app_store.settings import DOMAIN, PORT, STATIC_ROOT

class SendEmailRegister(object):
    def __init__(self, receiver, regitster_token):
        self.__receiver = receiver
        self.__register_token = regitster_token

    def send_email(self):
        se = SendEmailThread()
        se.set_sender()
        se.set_subject("新用户注册验证")
        se.set_receiver([self.__receiver])
        href = DOMAIN + ":" + PORT + "/confirm_user/" + self.__register_token + "/"
        html = """<a href=\"""" + href + """\">验证用户并确认注册</a></br>"""
        se.set_html(html)
        se.set_image(os.path.join(STATIC_ROOT, 'image', 'logo.png'), u'XX科技.png')
        se.start()
    

二、使用django.core.mail模块

    <deliver_email_thread.py>

    #!/usr/bin/env python2.7.3

__author__ = 'simba'
# -*- coding: utf-8 -*-

from django.core.mail import EmailMultiAlternatives
from time import sleep
import threading
from app_store.settings import DEBUG

class DeliverEmailThread(threading.Thread):
    def __init__(self, subject, body, sender, receiver_list):
        super(DeliverEmailThread, self).__init__()
        self.__sender = sender
        if not type(receiver_list) == list:  #收件人必须为链表
            raise ValueError, 'Invalid Argument'
        self.__receiver = receiver_list
        self.__email = EmailMultiAlternatives(subject=subject, body=body, from_email=self.__sender, to=self.__receiver)
        self.__email.content_subtype = "html"  # 主内体现在变成 text/html
        self.__fail_silently = DEBUG       #根据settings.py中的DEBUG值设置是否打印调试信息

    #附件
    def set_file(self, file_path):
        self.__email.attach_file(file_path)

    #发送邮件
    def run(self):
        try:
            self.__email.send(self.__fail_silently)
            sleep(5)  #避免邮件没有发送完成就调用了quit()
            return True
        except Exception, e:
            return False


<send_email_certify.py>

#!/usr/bin/env python2.7.3

__author__ = 'simba'
# -*- coding: utf-8 -*-

from django.template import loader
from deliver_email_thread import DeliverEmailThread
from app_store.settings import DOMAIN, PORT, STATIC_ROOT, EMAIL_HOST_USER
import os

class SendEmailCertify(object):
    def __init__(self, receiver, regitster_token):
        self.__receiver = receiver
        self.__sender = EMAIL_HOST_USER
        self.__register_token = regitster_token

    def send_email(self):
        subject = u'新用户注册验证'
        body = loader.render_to_string('mail_certiry_template.html',
            {'DOMAIN':DOMAIN, 'PORT':PORT, 'register_token':self.__register_token,}
        )
        image_path = os.path.join(STATIC_ROOT, 'image', 'logo.png')
        try:
            email = DeliverEmailThread(subject, body, self.__sender, [self.__receiver])
            email.set_file(image_path)
            email.start()
        except Exception, e:
            pass


三、使用方式如下:

    <config.py>

    __author__ = 'simba'
# coding=utf-8
#当使用587端口时,必须开启TLS,此时使用TLS链接,不使用SSL链接;
#当使用465端口时,必须关闭TLS,此时使用SSL链接,不使用TLS链接。

#登陆邮箱的用户名(必须包括域名)
UserName = 'username@163.com'
#登陆邮箱的密码
Password = 'aaa888'
#邮箱服务器
SmtpServer = 'smtp.163.com'
#邮箱服务器端口
SmtpPort = 587
#是否开启TLS
UseTLS = True
#邮箱地址
EmailAddress = 'username@163.com'


    在django的view.py文件中使用:

        timestamp = int(time.time())  #获取13位的UNIX时间戳
              md5_string = email + str(timestamp)
          token = hashlib.md5(md5_string.encode('utf-8')).hexdigest()
    SendEmailRegister(email, token).send_email()
    #SendEmailCertify(email, token).send_email()
                                                                    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值