本文介绍Django的邮件发送。
设置伪STMP服务器
发送邮件需要一个SMTP服务器。SMTP全称是 Simple Mail Transfer Protocal, 它是一个软件,知道如何发送邮件。在生产环境中,我们需要真实的SMTP服务,后面章节我们会介绍到,但目前,我们可以使用一个伪SMTP。这里使用的是smtp4dev。官网安装说明网址:
https://github.com/rnwood/smtp4dev/wiki/Installation
我们可以看到,它可以用dotnet或docker运行,我更喜欢用docker。首先安装好docker,然后运行:
docker run –rm -it -p 3000:80 -p 2525:25 rnwood/smtp4dev
这样本机的2525就是smtp端口,3000就是管理端口。
我们访问 http://localhost:3000 , 可以看到管理页面,有点类似outlook或其他邮件客户端,当我们通过程序发送邮件,可以在该界面查看相关信息。
配置邮件后端
邮件后端本质是发送邮件时的响应引擎。有以下几种:
- SMTP。默认,通过smtp服务器将邮件发送出去。
- Console。使用该引警,发送邮件的相关信息显示在控制台。
- File。发送邮件到文件。
- Locmem。发送邮件到本地内存。
- Dummy。发送邮件不做任何事情。
绝大多数时候,我们都使用SMTP,有些时候或许也会用到Console。我们到settings.py里设置一下。
…
EMAIL_BACKEND = ‘django.core.mail.backends.smtp.EmailBackend’
EMAIL_HOST = ‘localhost’
EMAIL_HOST_USER = ”
EMAIL_HOST_PASSWORD = ”
EMAIL_PORT = 2525
DEFAULT_FROM_EMAIL = ‘kelemi001@gmail.com’
…
EMAIL_BACKEND也可以设置成其他引擎,比如console, 默认的STMP的这句实际上可以省略,我们这里也明确标出来。由于伪SMTP,用户密码都为空。DEFAULT_FROM_EMAIL是可选的。
发送邮件
修改 playground — views,我们测试邮件发送功能。
from django.core.mail import send_mail, mail_admins, BadHeaderError
def say_hello(request):
try:
send_mail(‘subject’, ‘message’, ‘kelemi001@gmail.com’,
[‘chenyongping001@gmail.com’])
except BadHeaderError:
pass
…
邮件发送使用 send_mail,还有一个是send_mass_mail用于批量发送。send_mail第一个参数是主题;第二个是消息;第三个是发送人,设置的话覆盖settings.py的设置;第四个参数是收件人列表。另外由于发送过程可能出错,所以用BadHeaderError捕捉错误。
刷新页面 /playground/hello , 然后访问 smtp4dev管理页面:
http://127.0.0.1:3000
能看到发送的邮件信息。
可以给网站管理员发送邮件,使用mail_admins。
首先,在settings.py中设置管理员邮件,这是一个元组列表。
…
ADMINS = [
(‘kelemi’, ‘kelemi001@gmail.com’)
]
…
然后,修改say_hello:
..
def say_hello(request):
try:
mail_admins(‘subject’, ‘message’, html_message=’message’)
except BadHeaderError:
pass
…
这里消息我们设置了两个,一个是纯文件消息,一个是html消息。客户端如果能显示html邮件消息就显示html的,不行的就显示纯文本,尽管现在几乎没有客户端不支持html了。我们查看smtp4dev后台,也能看到邮件消息与前面的的区别。
附加文件
之前的send_mail,mail_admins,在内部实际都使用了EmailMessage类,这一节我们就用EmailMessage实现,高级功能比如附件文件,抄送,密送等都需要用这个类。
…
from django.core.mail import EmailMessage, BadHeaderError
def say_hello(request):
try:
message = EmailMessage(‘subject’, ‘message’,
‘from@kelemi.top’, [‘to@kelemi.top’])
message.attach_file(‘playground/static/images/dog.jpg’)
message.send()
except BadHeaderError:
pass
…
我们调用EmailMessage类,返回对象message,然后进行附件文件,并进行发送。完成后我们访问页面 /playground/hello,再查看 http://127.0.0.1:3000,能看到已成功附加图片了。
这里需要注意的是附件文件的路径是相对于项目根目录,我们在playground应用下新建了static及images文件夹,所以dog.jpg路径是 playground/static/images/dog.jpg。
发送模板邮件
在程序中,有时需要动态生成邮件,这就需要用到模板邮件。可以使用 django-templated-mail.
安装:
pipenv install django-templated-mail
再新建模板:playground–templates-emails-hello.html.
{% block subject%}this is a long subject {%endblock%}
{%block html_body%}
<h1>Hello</h1>
My name is {{name}}
{%endblock%}
再回到 playground –views.py。修改:
…
from templated_mail.mail import BaseEmailMessage
def say_hello(request):
try:
message = BaseEmailMessage(
template_name=’emails/hello.html’,
context={“name”: “kelemi”}
)
message.send([‘to@kelemi.top’])
except BadHeaderError:
pass
…
我们导入BaseEmailMessage, 该类传入模板文件名以及上下文键值对。刷新网页后,能在 http://127.0.0.1:3000看到动态修改了名字的模板邮件。
小结
在本文介绍了如何在Django中发送邮件,下一篇计划介绍Django的后台任务管理。