Django笔记三十八之发送邮件
本文首发于公众号:Hunter后端
原文链接:Django笔记三十八之发送邮件
这一篇笔记介绍如何在 Django 中发送邮件。
在 Python 中,提供了 smtplib 的邮件模块,而 Django 在这个基础上对其进行了封装,我们可以通过 django.core.mail 来调用。
以下是本篇笔记的目录:
- 邮件配置项
- send_mail
- EmailMessage
- 复用邮件发送连接
- 开发阶段调试设置
1、邮件配置项
在正式发送邮件前,我们需要在 settings.py 里设置几个参数,如下:
# hunter/settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'hunterxxxx04@163.com'
EMAIL_HOST_PASSWORD = 'JBDMVIXSHYxxxxx'
EMAIL_USE_SSL = True
EMAIL_USE_TLS = False
这些配置项在 log 日志记录那一篇笔记中有过介绍,那是我们指定日志等级发送邮件的功能,这里再做一下简单的介绍。
EMAIL_BACKEND 是我们指定的邮箱后端,在后面我们会介绍在开发调试阶段的时候可以设置的其他值
EMAIL_HOST 发送邮箱的主机地址,这里我们使用的是 163 邮箱的地址
EMAIL_PORT EMAIL_HOST 使用的端口
EMAIL_HOST_USER 发件人邮箱地址
EMAIL_HOST_PASSWORD 163 邮箱开启了 SMTP 服务提供的授权码
EMAIL_USE_SSL 与 SMTP 服务器对话时是否使用隐式 TLS 连接,这种类型被称为 SSL,通常在 465 端口使用,这个字段与 EMAIL_USE_TLS 是互相排斥的,只能设置一个为 True
EMAIL_USE_TLS 与 SMTP 服务器对话是否使用 TLS 连接,一般在 587 端口
以上就是在 Django 里使用 163 邮箱的一个配置项示例。
2、send_mail
配置好之后我们就可以尝试发送一下邮件,最简单的使用示例如下:
from django.core.mail import send_mail
send_mail(
subject="subject 主题",
message="邮件主体",
from_email="hunterxx@163.com",
recipient_list=["120460xxxx@qq.com"],
)
在上面的调用中,subject 是发送的邮件的标题,
message 是邮件发送的正文内容。
from_email 是发送邮件的邮箱
recipient_list 是接收收件人列表,可以接收多个邮箱地址
对于 message 参数,接收的是纯文本信息,会将参数内容直接显示在邮件正文,如果是想对文本进行更多操作,比如加大字体,加粗,或者加上表格等操作,可以使用 html_message 参数来替代 message 参数。
比如:
send_mail(
subject="subject 主题",
from_email="hunterxx@163.com",
recipient_list=["120460xxxx@qq.com"],
html_message="<h1>html main body</h1>"
)
在这里,html_message 将参数内容当作一个 html 文本进行解析,发送邮件后就可以在接收邮箱看到大号的文本字体了。
发送批量邮件
如果有批量发送邮件的需求,可以使用 send_mass_mail 方法。
from django.core.mail import send_mass_mail
message_1 = ("邮件标题1", "邮件正文1", "hunterxxx@163.com", ["120460xxxx@qq.com"])
message_2 = ("邮件标题2", "邮件正文2", "hunterxxx4@163.com", ["120460xxx6@qq.com"])
send_mass_mail(
(message_1, message_2)
该方法接收列表参数,其中列表的每一个元素的参数和参数顺序都是固定的,分别是邮件标题,正文,邮件发送人,和邮件接收人列表。
注意: 因为批量发送的参数是固定的,所以并不支持 send_mail 里的 html_message 参数。
3、EmailMessage
前面介绍的 send_mail() 方法简单可用,但是并不支持邮件里的附件、抄送等功能,接下来我们使用 EmailMessage 这个类来实现这些额外的功能。
以下是使用 EmailMessage 实现发送邮件的简单示例:
from django.core.mail import EmailMessage
email = EmailMessage(
subject="邮件标题",
body="邮件主体",
from_email="hunterxxx@163.com",
to=["120460xxx@qq.com"],
)
email.send()
参数名称与 send_mail() 略有不同,这里的邮件正文是 body,接收人列表为 to。
这里在实例化 EmailMessage 之后,调用 send() 方法即可发送邮件。
除了上面的这些参数,还有 bcc,实现的是密送功能,也是邮件接收人列表,cc 是抄送人列表。
还有 attachments 参数,实现的是附件功能,接下来介绍几种发送附件的方式:
发送附件
1. attachments 参数
我们可以直接在 EmailMessage() 中添加附件参数,attachments 参数接收一个列表,列表元素也是一个列表,内层的这个列表接收三个元素,第一个元素为文件名,第二个元素为文件内容,第三个元素为指定的附件的 MIME 类型,第三个参数省略的话就会参考附件的文件名自动选择。
我们在系统根目录下创建两个文件 a.txt, b.txt,然后实现示例如下:
from django.core.mail import EmailMessage
attachments = []
for file_name in ["./a.txt", "./b.txt"]:
with open(file_name, "r") as f:
content = f.read()
attachments.append((file_name, content))
email = EmailMessage(
subject="邮件标题",
body="邮件主体",
from_email="hunterxxxx@163.com",
to=["120460xxxx@qq.com"],
attachments=attachments,
)
email.send()
2. attach() 方法
除了直接在 EmailMessage 实例中添加参数,我们还可以使用 attach() 方法。
示例如下:
email = EmailMessage(
subject="邮件标题",
body="邮件主体",
from_email="hunterxxxx@163.com",
to=["120460xxxx@qq.com"],
)
file_name_1 = "./a.txt"
f = open(file_name_1, "r")
file_content_1 = f.read()
f.close()
email.attach(file_name_1, file_content_1)
email.send()
3. attach_file() 方法
还有一个方式是使用 attach_file() 方法,参数内容是文件路径+文件名,系统会自动为我们解析该文件:
email = EmailMessage(
subject="邮件标题",
body="邮件主体",
from_email="hunterxxxx@163.com",
to=["120460xxx@qq.com"],
)
email.attach_file("./b.txt")
email.send()
EmailMessage 发送 html 正文
前面介绍了在 send_mail() 方法可以通过 html_message 的参数发送 html 页面的邮件,在 EmailMessage 也可以实现,但是需要修改 content_subtype 属性。
默认情况下,EmailMessage.content_subtype 是 "plain",我们将其改为 "html" 即可发送 html 页面的邮件。
email = EmailMessage(
subject="邮件标题",
body="<h1>邮件主体</h1>",
from_email="hunterxxxx@163.com",
to=["120460xxx@qq.com"],
)
email.content_subtype = "html"
email.send()
4、复用邮件发送连接
因为发送邮件涉及到网络连接及可能存在的大量数据的传送,比如附件。
所以,如果是在接口中有发送邮件的需求,我们可以通过 celery 的异步任务实现发送邮件的功能。
而邮件的发送会涉及到 SMTP 连接的创建和关闭,所以复用连接也是一个好的方式。
这里介绍两种方式:
send_messages
send_messages() 方法接收 EmailMessage 实例列表,然后实现批量发送的功能:
from django.core import mail
from django.core.mail import EmailMessage
email_1 = EmailMessage(
subject="邮件标题1",
body="邮件主体1",
from_email="hunterxxxx@163.com",
to=["120460xxxx@qq.com"],
)
email_2 = EmailMessage(
subject="邮件标题2",
body="邮件主体2",
from_email="hunterxxxx@163.com",
to=["120460xxxx@qq.com"],
)
connection = mail.get_connection()
messages = [email_1, email_2]
connection.send_messages(messages)
手动控制 connection
我们可以手动控制 connection 的创建和关闭。
from django.core import mail
connection = mail.get_connection()
email_1 = mail.EmailMessage(
subject="邮件标题1",
body="邮件主体1",
from_email="hunterxxx@163.com",
to=["120460xxx@qq.com"],
connection=connection
)
email_1.send()
email_2 = mail.EmailMessage(
subject="邮件标题2",
body="邮件主体2",
from_email="hunterxxxx@163.com",
to=["120460xxxx@qq.com"],
)
email_3 = mail.EmailMessage(
subject="邮件标题3",
body="邮件主体3",
from_email="hunterxxxx@163.com",
to=["120460xxxx@qq.com"],
)
messages = [email_2, email_3]
connection.send_messages(messages)
connection.close()
在这里,email_1 的调用增加了 connection 参数,email_2 和 email_3 也是使用 connection 进行的批量发送
这个过程中,connection 一直没有关闭,所以复用的是同一个连接,直到最后调用 close() 才算是手动关闭了这个 connection 连接。
5、开发阶段调试设置
在开发阶段,我们调试发送邮件功能的时候,有时候并不想每次都真的发送邮件给指定账户,尽管可能是测试账号,我们有时候只想看一下输出的内容,可以更改邮箱配置的后端
console
我们可以在 settings.py 里设置:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
这样,在调用我们前面的 send 方法后,系统就不会发送邮件给 to 的接收人列表了,而是会在控制台输出我们的邮件信息:
类似如下:
Content-Type: text/html; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: =?utf-8?b?6YKu5L2qCH6aKY?=
From: hunterxiong04@163.com
To: 120460xxxx@qq.com
Date: Fri, 17 Feb 2023 18:01:21 -0000
Message-ID:
<167665688132.1114.884170460108140763@1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa>
<h1>邮件主体</h1>
-------------------------------------------------------------------------------
filebased
在调试阶段,我们还可以指定将邮件的内容输出到文件,同样的修改邮件后端配置:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = './emails_file'
这里设置了邮件后端为文件,EMAIL_FILE_PATH 则是指定了邮件内容放到系统根目录下的 emails_file 文件中。
调用了发送邮件的函数后,在这个文件夹下就会多出一个文件,文件内容是我们前面在 console 控制台输出的内容
如果想获取更多后端相关文章,可扫码关注阅读:

Django笔记三十八之发送邮件的更多相关文章
- Django笔记三十之log日志记录详解
本文首发于公众号:Hunter后端 原文链接:Django笔记三十之log日志的记录详解 这一节介绍在 Django 系统里使用 logging 记录日志 以下是一个简单的 logging 模块示例, ...
- Django笔记二十八之数据库查询优化汇总
本文首发于公众号:Hunter后端 原文链接:Django笔记二十八之数据库查询优化汇总 这一篇笔记将从以下几个方面来介绍 Django 在查询过程中的一些优化操作,有一些是介绍如何获取 Django ...
- Django笔记三十二之session登录验证操作
本文首发于公众号:Hunter后端 原文链接:Django笔记三十二之session登录验证操作 这一篇笔记将介绍 session 相关的内容,包括如何在系统中使用 session,以及利用 sess ...
- 【Unity 3D】学习笔记三十八:角色控制器
角色控制器 在unity中,已经帮我们实现的上下左右跳等动作,并将他们封装成了角色控制器.角色控制器保存在unity标准资源包中,能够说是很的强大.能够模拟第一或者第三人称视角.不受刚体的限制,很适用 ...
- JavaScript学习笔记(三十八) 复制属性继承
复制属性继承(Inheritance by Copying Properties) 让我们看一下另一个继承模式—复制属性继承(inheritance by copying properties).在这 ...
- PHP学习笔记三十八【下载】
<?php //演示下载一个图片 $file_name="SunSet.jpg"; $file_name=iconv("utf-8","gb23 ...
- 论文阅读笔记三十八:Deformable Convolutional Networks(ECCV2017)
论文源址:https://arxiv.org/abs/1703.06211 开源项目:https://github.com/msracver/Deformable-ConvNets 摘要 卷积神经网络 ...
- Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)
在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...
- Django笔记二十之手动编写migration文件
本文首发于公众号:Hunter后端 原文链接:Django笔记二十之手动编写migration文件 前面介绍过,migration 文件主要记录的是 Django 系统 model 的变化,然后通过 ...
- Django笔记二十四之数据库函数之比较和转换函数
本文首发于公众号:Hunter后端 原文链接:Django笔记二十四之数据库函数之比较和转换函数 这一篇笔记开始介绍几种数据库函数,以下是几种函数及其作用 Cast 转换类型 Coalesce 优先取 ...
随机推荐
- unity更改c#文件名的小tip
今天偶然知道了一个在Unity中更改代码文件名的小技巧--最好先在Unity的project视图里找到文件,改完后再去visual studio等代码编辑器里改里面的类名. 以前都没注意,想起来要改某 ...
- python之自动化连连看脚本-第一关不动-小记
(如想转载,请联系博主或贴上本博地址) 仅供学习python之用,勿用做商业用途.运行环境为1920*1080屏幕,python3.7,win7,谷歌浏览器版本 75.0.3770.100. 参考ht ...
- 禅道 docker 部署
官方文档:https://hub.docker.com/r/idoop/zentao 1.创建本地目录:mkdir -p /data/zbox 2.启动容器: sudo docker run -itd ...
- Checkmk监控工具使用手册
其实用法Checkmk官网文档很全面:https://docs.checkmk.com/latest/en/intro_setup.html 顺着beginner's guide章节看完基本就能上手, ...
- React数字滚动组件 numbers-scroll
数字滚动组件,也可以叫数字轮播组件,这个名字一听就是非常普通常见的组件,第一反应就是想找找网上大佬的东西顶礼膜拜一下,这一搜,还真是没找到趁手的╮(╯▽╰)╭. 最近接了大屏的需求,数字滚动肯定是免不 ...
- SpringBoot笔记--配置文件分类+yaml相关知识+读取配置文件内容
配置文件 要是需要使用自己的配置替换默认配置时,需要使用后缀名为application.properties或者application.yml(application.yaml)进行配置 当然,几个文 ...
- 基于springboot实现SSM整合
(1)SpringBoot整合Spring(不存在) (2)SpringBoot整合SpringMVC(不存在) (3)SpringBoot整合MyBatis(主要) 一.新建springboot项目 ...
- 实现一个CRDT工具库——PSet
PSet 这段代码实现了一个PSet,即Positive Set,是GSet的扩展.PSet是一个集合,支持添加和删除元素,但是不支持重复元素.PSet的实现是通过两个GSet来实现的,一个GSet存 ...
- 人人都学会APP开发 提高就业竞争力 简单实用APP应用 安卓浏览器APP 企业内部通用APP制作 制造业通用APP
安卓从2009年开始流程于手机.平板,已经是不争的非常强大生产力工具,更为社会创造非常高的价值, 现在已经是202X年,已经十几年的发展,安卓平台已经无所不在. 因此建议人人都学学APP制作,简易入门 ...
- 【ACM算法竞赛日常训练】DAY10题解与分析【月月给华华出题】【华华给月月出题】| 筛法 | 欧拉函数 | 数论
DAY10共2题: 月月给华华出题 华华给月月出题 难度较大. 作者:Eriktse 简介:211计算机在读,现役ACM银牌选手力争以通俗易懂的方式讲解算法!️欢迎关注我,一起交流C++/Python ...