django搭建博客六邮件模板和邮件工具类

2022年04月23日 0评论 591阅读 1喜欢

邮件发送工具类

基于from django.core.mail import send_mail 抽取公共的逻辑封装成基本的EmailSender,其他类型的邮件则继承该类,定义好邮件内容模板路径以及模板上下文参数即可。这里利用django的template将邮件内容抽离出来变成模板,也方便了后期页面样式调整。

from django.urls import reverse
from django.utils.crypto import get_random_string
from system.models import EmailRecord, User
from django.core.mail import send_mail
from django.template.loader import render_to_string
from myblog.email_settings import EMAIL_FROM
from myblog.settings import SITE_URL, SITE_NAME
import logging

logger = logging.getLogger(__name__)


class EmailSender(object):
    template_name = ""
    from_email = EMAIL_FROM
    site_url = SITE_URL
    site_name = SITE_NAME

    def __init__(self, email_type="", username=""):
        self.email_type = email_type
        self.receiver = self.get_receiver(username)
        self.record = EmailRecord(email_type=email_type, code=get_random_string(16), receiver=self.receiver)
        self.title = self.record.get_email_type_display()

    @staticmethod
    def get_receiver(username=""):
        try:
            user = User.objects.only("username", "id", "email").get(username=username)
            return user
        except User.DoesNotExist:
            raise ValueError("用户名不存在")

    def get_template_context(self):
        return {"title": self.title, "receiver": self.receiver, "site_name": self.site_name,
                "site_url": self.site_url}

    def send(self, *args, **kwargs):
        context = self.get_template_context(*args, **kwargs)
        subject = f"{self.site_name}{self.title}邮件"
        html_message = render_to_string(self.template_name, context)
        try:
            send_mail(from_email=self.from_email,
                      subject=subject,
                      message="",
                      recipient_list=[self.receiver.email],
                      html_message=html_message)
            self.record.succeed = True
            logger.info(f"[receiver: {self.receiver.email}]邮件发送成功")
        except Exception as e:
            self.record.succeed = False
            logger.info(f"[receiver: {self.receiver.email}][msg:{e}]邮件发送失败")
        self.record.save()

注册激活模板

新建\myblog\templates\user\email-register-active.html

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{{ title|default:'个人博客' }}通知邮件</title>
</head>
<body>
<table style="width: 600px; border: 1px solid #ddd; border-radius: 3px; color: #555; font-family: 'Helvetica Neue Regular',Helvetica,Arial,Tahoma,'Microsoft YaHei','San Francisco','微软雅黑',' Hiragino Sans GB',STHeitiSC-Light; font-size: 12px; height: auto; margin: auto; overflow: hidden; text-align: left; word-break: break-all; word-wrap: break-word;"
       cellspacing="0" cellpadding="0" border="0">
    <tbody style="margin: 0; padding: 0;">
    <tr style="background-color: #393D49; height: 60px; margin: 0; padding: 0;">
        <td style="margin: 0; padding: 0;">
            <div style="color: #5EB576; margin: 0; margin-left: 30px; padding: 0;">
                <a style="font-size: 14px; margin: 0; padding: 0; color: #5EB576; text-decoration: none;"
                   href="{{ site_url|default:'#' }}" target="_blank" rel="noopener">{{ site_name|default:'个人博客' }}——{{ title|default:'这是一封注册激活' }}通知邮件</a>
            </div>
        </td>
    </tr>
    <tr style="margin: 0; padding: 0;">
        <td style="margin: 0; padding: 30px;">
            <p style="line-height: 20px; margin: 0; margin-bottom: 10px; padding: 0;"> Hi,
                <em style="padding:0;font-weight:700;color:#6e6e6e;font-size:16px">{{ receiver.username|default:'XXX' }}</em>,你好</p>
            <p style="color:#6e6e6e;font-size:13px;line-height:24px">欢迎您注册<em
                    style="padding:0;font-weight:700;color:#6e6e6e;font-size:16px">[{{ site_name|default:'个人博客' }}博客]</em>,请根据下面的信息完成激活,登陆后如有密码修改需要,可以修改密码!
            </p>
            <table style="width:100%;border-top:1px solid #eee;border-left:1px solid #eee;color:#6e6e6e;font-weight:normal;"
                   cellspacing="0" cellpadding="0" border="0">
                <thead>
                <tr>
                    <th colspan="2"
                        style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;background:#f2f2f2;font-weight:700;font-size:16px">
                        您的注册信息
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;width:100px">
                        用户名
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        {{ receiver.username|default:'xxxx' }}
                    </td>
                </tr>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;width:100px">
                        邮箱
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        {{ receiver.email|default:'xxxxxxx@xxx.com' }}
                    </td>
                </tr>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center">
                        密码
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        {{ password|default:'123456' }}
                    </td>
                </tr>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;width:100px">
                        激活方式
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        <a href="{{ url|default:'#' }}"
                           style="background-color: #009E94; color: #fff; display: inline-block; height: 32px; line-height: 32px; margin: 0 15px 0 0; padding: 0 15px; text-decoration: none;"
                           target="_blank" rel="noopener">立即激活邮箱</a>
                    </td>
                </tr>
                </tbody>
            </table>
            <p style="line-height: 20px; margin-top: 20px; padding: 10px; background-color: #f2f2f2; font-size: 12px;">
                如果该邮件不是由你本人操作,请勿进行激活!否则你的邮箱将会被他人绑定。 </p>
        </td>
    </tr>
    <tr style="background-color: #fafafa; color: #999; height: 35px; margin: 0; padding: 0; text-align: center;">
        <td style="margin: 0; padding: 0;">系统邮件,请勿直接回复 | {% now "Y/m/d H:m:s" %}</td>
    </tr>
    </tbody>
</table>
</div>
</body>
</html>

页面效果:
在这里插入图片描述

密码重置邮件模板

新建myblog\templates\user\email-password-reset.html

内容如下

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{{ title|default:'密码重置' }}通知邮件</title>
</head>
<body>
<table style="width: 600px; border: 1px solid #ddd; border-radius: 3px; color: #555; font-family: 'Helvetica Neue Regular',Helvetica,Arial,Tahoma,'Microsoft YaHei','San Francisco','微软雅黑',' Hiragino Sans GB',STHeitiSC-Light; font-size: 12px; height: auto; margin: auto; overflow: hidden; text-align: left; word-break: break-all; word-wrap: break-word;"
       cellspacing="0" cellpadding="0" border="0">
    <tbody style="margin: 0; padding: 0;">
    <tr style="background-color: #393D49; height: 60px; margin: 0; padding: 0;">
        <td style="margin: 0; padding: 0;">
            <div style="color: #5EB576; margin: 0; margin-left: 30px; padding: 0;">
                <a style="font-size: 14px; margin: 0; padding: 0; color: #5EB576; text-decoration: none;"
                   href="{{ site_url|default:'#'}}" target="_blank" rel="noopener">{{ site_name|default:'个人博客' }}——{{ title|default:'密码重置' }}通知邮件</a>
            </div>
        </td>
    </tr>
    <tr style="margin: 0; padding: 0;">
        <td style="margin: 0; padding: 30px;">
            <p style="line-height: 20px; margin: 0; margin-bottom: 10px; padding: 0;"> Hi,
                <em style="padding:0;font-weight:700;color:#6e6e6e;font-size:16px">{{ receiver.username|default:'XXX' }}</em>,你好</p>
            <p style="color:#6e6e6e;font-size:13px;line-height:24px">请使用下面的信息完成密码修改!</p>
            <table style="width:100%;border-top:1px solid #eee;border-left:1px solid #eee;color:#6e6e6e;font-size:auto;font-weight:normal"
                   cellspacing="0" cellpadding="0" border="0">
                <thead>
                <tr>
                    <th colspan="2"
                        style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;background:#f2f2f2;font-weight:700;font-size:16px">
                        您的个人信息
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;width:100px">
                        用户名
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        {{ receiver.username|default:'XXX' }}
                    </td>
                </tr>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;width:100px">
                        登录邮箱
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        {{ receiver.email|default:'xxxxxxx@xxx.com' }}
                    </td>
                </tr>
                <tr>
                    <td style="padding:10px 0;border-right:1px solid #eee;border-bottom:1px solid #eee;text-align:center;width:100px">
                        修改方式
                    </td>
                    <td style="padding:10px 20px 10px 30px;border-right:1px solid #eee;border-bottom:1px solid #eee;line-height:30px">
                        <a href="{{ url|default:'#'}}"
                           style="background-color: #009E94; color: #fff; display: inline-block; height: 32px; line-height: 32px; margin: 0 15px 0 0; padding: 0 15px; text-decoration: none;"
                           target="_blank" rel="noopener">去重置密码</a>
                    </td>
                </tr>
                </tbody>
            </table>
            <p style="line-height: 20px; margin-top: 20px; padding: 10px; background-color: #f2f2f2; font-size: 12px;">
                有人要求重设您在[{{ site_name|default:'个人博客' }}]的密码,若不是您本人请求,请忽略本邮件。</p>
        </td>
    </tr>
    <tr style="background-color: #fafafa; color: #999; height: 35px; margin: 0; padding: 0; text-align: center;">
        <td style="margin: 0; padding: 0;">系统邮件,请勿直接回复 | {% now "Y/m/d H:m:s" %}</td>
    </tr>
    </tbody>
</table>
</div>
</body>
</html>

页面效果如下:
在这里插入图片描述

评论审核邮件模板

新建myblog\templates\user\email-comment-check.html

内容如下

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{{ title|default:'评论审核' }}通知邮件</title>
</head>
<body>
<table style="width: 600px; border: 1px solid #ddd; border-radius: 3px; color: #555; font-family: 'Helvetica Neue Regular',Helvetica,Arial,Tahoma,'Microsoft YaHei','San Francisco','微软雅黑',' Hiragino Sans GB',STHeitiSC-Light; font-size: 12px; height: auto; margin: auto; overflow: hidden; text-align: left; word-break: break-all; word-wrap: break-word;"
       cellspacing="0" cellpadding="0" border="0">
    <tbody style="margin: 0; padding: 0;">
    <tr style="background-color: #393D49; height: 60px; margin: 0; padding: 0;">
        <td style="margin: 0; padding: 0;">
            <div style="color: #5EB576; margin: 0; margin-left: 30px; padding: 0;">
                <a style="font-size: 14px; margin: 0; padding: 0; color: #5EB576; text-decoration: none;"
                   href="{{ site_url|default:'#' }}" target="_blank" rel="noopener">{{ site_name|default:'个人博客' }}——{{ title|default:'评论审核' }}通知邮件</a>
            </div>
        </td>
    </tr>
    <tr style="margin: 0; padding: 0;">
        <td style="margin: 0; padding: 30px;">
            <p style="line-height: 20px; margin: 0; margin-bottom: 10px; padding: 0;"> Hi,
                <em style="padding:0;font-weight:700;color:#6e6e6e;font-size:16px">主人</em>,你好</p>
            <p style="color:#6e6e6e;font-size:13px;line-height:24px">您有一条新的留言,摘要信息请见下表。</p>
            <table style="font-size:14px;text-align:center;border:1px solid #ccc;table-layout:fixed;width:500px;"
                   cellspacing="0">
                <thead>
                <tr>
                    {#文章评论#}
                    <th style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:normal;color:#a0a0a0;background:#eee;border-color:#dfdfdf;"
                        width="280px;">文章
                    </th>
                    <th style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:normal;color:#a0a0a0;background:#eee;border-color:#dfdfdf;"
                        width="270px;">内容
                    </th>
                    <th style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:normal;color:#a0a0a0;background:#eee;border-color:#dfdfdf;"
                        width="110px;">操作
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    {#文章评论#}
                    <td style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
                        《{{ comment.article.title|default:'xxxxxxxxxxxxx' }}》
                    </td>
                    <td style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ comment.content|default:'xxxxxxxxxxxxxx'|safe|truncatechars_html:'15' }}</td>
                    <td style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
                        <a href="{{ url|default:'#' }}"
                           style="background-color: #009E94; color: #fff; display: inline-block; height: 32px; line-height: 32px; margin: 0 15px 0 0; padding: 0 15px; text-decoration: none;"
                           target="_blank" rel="noopener">审核通过</a></td>
                </tr>
                </tbody>
            </table>
        </td>
    </tr>
    <tr style="background-color: #fafafa; color: #999; height: 35px; margin: 0; padding: 0; text-align: center;">
        <td style="margin: 0; padding: 0;">系统邮件,请勿直接回复 | {% now "Y/m/d H:m:s" %}</td>
    </tr>
    </tbody>
</table>
</div>
</body>
</html>

页面效果如下:
\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jAkoLDEi-1650682723105)(assets/1650681433107.png)\]

评论审核通过邮件模板

新建myblog\templates\user\email-comment-notice.html

内容如下

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{{ title|default:'评论审核通过' }}通知邮件</title>
</head>
<body>
<table style="width: 600px; border: 1px solid #ddd; border-radius: 3px; color: #555; font-family: 'Helvetica Neue Regular',Helvetica,Arial,Tahoma,'Microsoft YaHei','San Francisco','微软雅黑',' Hiragino Sans GB',STHeitiSC-Light; font-size: 12px; height: auto; margin: auto; overflow: hidden; text-align: left; word-break: break-all; word-wrap: break-word;"
       cellspacing="0" cellpadding="0" border="0">
    <tbody style="margin: 0; padding: 0;">
    <tr style="background-color: #393D49; height: 60px; margin: 0; padding: 0;">
        <td style="margin: 0; padding: 0;">
            <div style="color: #5EB576; margin: 0; margin-left: 30px; padding: 0;">
                <a style="font-size: 14px; margin: 0; padding: 0; color: #5EB576; text-decoration: none;"
                   href="{{ site_url|default:'#' }}" target="_blank"
                   rel="noopener">{{ site_name|default:'个人博客' }}——{{ title|default:'评论审核通过' }}通知邮件</a>
            </div>
        </td>
    </tr>
    <tr style="margin: 0; padding: 0;">
        <td style="margin: 0; padding: 30px;">
            <p style="line-height: 20px; margin: 0; margin-bottom: 10px; padding: 0;"> Hi,
                <em style="padding:0;font-weight:700;color:#6e6e6e;font-size:16px">{{ comment.creator.username|default:'xxxxxxxxx' }}</em>,你好
            </p>
            <p style="color:#6e6e6e;font-size:13px;line-height:24px">您有一条留言通过了管理员的审核并显示在文章页面,摘要信息请见下表。</p>
            <table style="font-size:14px;text-align:center;border:1px solid #ccc;table-layout:fixed;width:500px;"
                   cellspacing="0">
                <thead>
                <tr>
                    {#文章评论#}
                    <th style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:normal;color:#a0a0a0;background:#eee;border-color:#dfdfdf;"
                        width="280px;">文章
                    </th>
                    <th style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:normal;color:#a0a0a0;background:#eee;border-color:#dfdfdf;"
                        width="270px;">内容
                    </th>
                    <th style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:normal;color:#a0a0a0;background:#eee;border-color:#dfdfdf;"
                        width="110px;">操作
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    {#文章评论#}
                    <td style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
                        《{{ comment.article.title|default:'xxxxxxxxxxxxxxxxx' }}》
                    </td>
                    <td style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ comment.content|default:'xxxxxxxxxxxxxxxx'|safe|truncatechars_html:'15' }}</td>
                    <td style="padding:5px 0;text-indent:8px;border:1px solid #eee;border-width:0 1px 1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
                        <a href="{{ url|default:'#' }}"
                           style="background-color: #009E94; color: #fff; display: inline-block; height: 32px; line-height: 32px; margin: 0 15px 0 0; padding: 0 15px; text-decoration: none;"
                           target="_blank" rel="noopener">查看留言</a></td>
                </tr>
                </tbody>
            </table>
        </td>
    </tr>
    <tr style="background-color: #fafafa; color: #999; height: 35px; margin: 0; padding: 0; text-align: center;">
        <td style="margin: 0; padding: 0;">系统邮件,请勿直接回复 | {% now "Y/m/d H:m:s" %}</td>
    </tr>
    </tbody>
</table>
</div>
</body>
</html>

页面效果如下:
在这里插入图片描述

评论回复邮件模板

新建myblog\templates\user\email-comment-reply.html

内容如下

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{{ title|default:'个人博客' }}通知邮件</title>
</head>
<body>
<table style="width: 600px; border: 1px solid #ddd; border-radius: 3px; color: #555; font-family: 'Helvetica Neue Regular',Helvetica,Arial,Tahoma,'Microsoft YaHei','San Francisco','微软雅黑',' Hiragino Sans GB',STHeitiSC-Light; font-size: 12px; height: auto; margin: auto; overflow: hidden; text-align: left; word-break: break-all; word-wrap: break-word;"
       cellspacing="0" cellpadding="0" border="0">
    <tbody style="margin: 0; padding: 0;">
    <tr style="background-color: #393D49; height: 60px; margin: 0; padding: 0;">
        <td style="margin: 0; padding: 0;">
            <div style="color: #5EB576; margin: 0; margin-left: 30px; padding: 0;">
                <a style="font-size: 14px; margin: 0; padding: 0; color: #5EB576; text-decoration: none;"
                   href="{{ site_url|default:'#' }}" target="_blank"
                   rel="noopener">{{ site_name|default:'个人博客' }}——{{ title|default:'评论回复' }}通知邮件</a>
            </div>
        </td>
    </tr>
    <tr style="margin: 0; padding: 0;">
        <td style="margin:40px auto;width:90%">
            {#文章评论#}
            <p>
                你好,{{ comment.parent.creator.username|default:'张三' }}。您曾在文章《{{ comment.parent.article.title|default:'xxxxxxx'|truncatechars:'10' }}》上发表评论:</p>
            <p style="background-color: #f5f5f5;border: 0px solid #DDD;padding: 10px 15px;margin:18px 0;">{{ comment.parent.content|default:'xxxxxxxxxxxxxxxx'|safe|truncatechars_html:'15' }}</p>
            <p>{{ comment.creator.username|default:'李四' }} 给您的回复如下:</p>
            <p style="background-color: #f5f5f5;border: 0px solid #DDD;padding: 10px 15px;margin:18px 0;">{{ comment.content|default:'XXXXXXXXX'|safe|truncatechars_html:15 }}</p>
            <p>您可以点击 <a style="text-decoration:none; color:#12addb" href="{{ url|default:'#' }}" rel="noopener"
                        target="_blank">查看回复的完整內容 </a>,欢迎再次光临 <a style="text-decoration:none; color:#12addb"
                                                                 href="{{ site_url|default:'#' }}" rel="noopener"
                                                                 target="_blank"> {{ site_name|default:'个人博客' }}网站 </a>。
            </p>

        </td>
    </tr>

    <tr style="background-color: #fafafa; color: #999; height: 35px; margin: 0; padding: 0; text-align: center;">
        <td style="margin: 0; padding: 0;">系统邮件,请勿直接回复 | {% now "Y/m/d H:m:s" %}</td>
    </tr>
    </tbody>
</table>
</div>
</body>
</html>

页面效果如下:
在这里插入图片描述

发表评论 取消回复

电子邮件地址不会被公开。

请输入以http或https开头的URL,格式如:https://oneisall.top