掌握Django(十四)–邮件发送

本文介绍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的后台任务管理。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注