如何使用Django发送电子邮件(附实例)

1,202 阅读9分钟

在本教程中,我们将学习如何使用Django通过你自己的应用程序发送电子邮件。我们将介绍如何配置Django SMTP连接,如何设置一个用于Django项目的应用密码,以及如何通过Django shell发送邮件。我们还将看看如何设置一个用于收集客户邮件的联系表单。

大多数网络应用程序使用电子邮件来管理关键的操作,如重设密码、账户激活、接收客户反馈、发送新闻简报和营销活动。这些任务大多需要像SendGridMailgun这样的专用服务。但是,如果你不指望你的网站获得大量的访问者,你实际上可以通过你的个人电子邮件提供商完成很多工作。

对于小型或测试项目来说,用你的个人电子邮件发送电子邮件是一个合理的选择,所以我们在这里将采取这种方法,以保持事情简单。然而,为你的生产网站使用你的个人电子邮件服务并不是一个好主意。你可以了解更多关于Gmail的发送限制,或者参考你的电子邮件提供商的限制。

注意:本教程的完整代码可以在GitHub上找到。

了解SMTP

SMTP(或称简单邮件传输协议)是一套确定电子邮件如何从发送方传输到接收方的规则。SMTP服务器使用该协议来发送和转发外发邮件。(请注意,其他协议管理电子邮件的接收方式)。

一个SMTP服务器总是有一个独特的地址,和一个用于发送邮件的特定端口,在大多数情况下是587。我们将看到在用Django发送邮件时,端口是如何被关注的。

由于我们将使用Gmail,我们将使用的地址是smtp.gmail.com ,端口是587。

现在让我们来看看如何用Django发送邮件。

创建一个Django项目

每个Django项目都应该有一个虚拟环境,因为我们不想搞乱项目的依赖关系。要创建一个,请运行以下程序。

python -m venv .venv

注意:如果你对虚拟环境不熟悉,请确保查看我们的Python虚拟环境指南

上面的命令创建了一个虚拟环境,名称为.venv 。要激活这个虚拟环境,你可以使用下面的方法。

source .venv/bin/activate

由于Django是一个第三方软件包,你必须用pip安装它。

pip install django

这将安装最新版本的Django,你可以用pip freeze

要创建一个Django项目,你需要调用命令行工具django-admin

django-admin startproject EmailProject

通过上面的命令,你创建的Django项目名称为EmailProject ,但你可以用任何你想要的名字来创建项目。

现在,进入到项目目录并运行服务器。

cd EmailProject
python manage.py runserver

运行Django服务器后,在浏览器中访问http://localhost:8000。你会看到一个自动生成的页面,上面有最新的Django发布说明。

Django local server

修改设置

在发送邮件之前,你需要修改设置文件,所以让我们用命令tree 来定位该文件。

注意:为了简单起见,我们将只使用UNIX(macOS或Linux)系统命令。

tree

tree 命令输出一个目录的文件结构。在这种情况下,由于我们没有给它一个具体的目录路径,如果我们在项目的根目录下,我们会得到类似于下面的东西。

├── EmailProject
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1 directory, 6 files

我们在本教程中要不断修改的文件是EmailProject 文件夹中的settings.py

settings.py 它包含了所有你需要的项目配置,并允许你设置自定义变量。正如Django文档所说,"一个设置文件只是一个带有模块级变量的Python模块"。

让我们来看看用Django发送电子邮件所需的设置。打开EmailProject/settings.py 文件,在文件的底部粘贴以下设置。

# EmailProject/settings.py

# Bottom of the file
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = ''
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''

让我们通过分析这些设置中的每一项来分解上面的代码。

电子邮件后端

EMAIL_BACKEND设置声明了我们的Django项目将用于连接SMTP服务器的后端。

这个变量指向smtp.EmailBackend 类,该类接收发送邮件所需的所有参数。我强烈建议你直接看一下Django源代码上的类构造函数。你会对这段代码的可读性感到惊讶。

注意:虽然这个类是默认的EMAIL_BACKEND ,但在Django的设置中明确规定,被认为是一个好的做法。

所有其他的邮件设置将基于这个EmailBackend类的构造函数。

电子邮件主机

EMAIL_HOST 设置是指你将使用的SMTP服务器域。这取决于你的电子邮件提供商。下面是一个表格,列出了三种常见的供应商所对应的SMTP服务器主机。

电子邮件提供商SMTP服务器主机
Gmailsmtp.gmail.com
Outlook/Hotmailsmtp-mail.outlook.com
雅虎smtp.mail.yahoo.com

我们现在把这个设置留空,因为我们以后会使用.env 文件,以避免硬编码的敏感密钥或每个站点的配置。你不应该在代码中直接设置凭证。

我们将使用Django Environ来解决这个问题。

电子邮件端口

EMAIL_PORT 的设置必须设置为587 ,因为它是大多数 SMTP 服务器的默认端口。对于个人电子邮件提供商来说,这一点仍然适用。

这个端口与TLS加密一起使用,以确保邮件发送的安全性。

电子邮件使用TLS

传输层安全(TLS)是整个网络上使用的一种安全协议,用于加密网络应用程序(Django)和服务器(SMTP服务器)之间的通信。

最初,我们将EMAIL_USE_TLS 变量设置为True 。这意味着Django将使用传输层安全来连接SMTP服务器并发送邮件。(这对个人电子邮件提供商来说是强制性的)。

电子邮件主机用户

EMAIL_HOST_USER 的设置是你的个人电子邮件地址。暂时留空,因为我们将使用django-environ 来设置所有这些凭证。

电子邮件主机密码

EMAIL_HOST_PASSWORD 设置是你将从你的电子邮件帐户获得的应用程序密码--我们将在本节之后进行的过程。

同样的情况:把这个设置留空,因为我们以后会使用环境变量。

在Gmail中设置一个应用程序密码

要使用EMAIL_HOST_PASSWORD 设置,你需要激活较不安全的应用程序访问,并有一个来自你个人电子邮件地址的应用程序密码。

如果你不激活较不安全的应用程序访问,你可能会得到一个SMTPAuthenticationError ,因为Django没有办法遵守谷歌的安全协议。

你可以选择使用你的正常密码,但这将比使用应用程序密码更有风险。我的建议是创建一个新的Gmail账户,或者使用一个 "测试 "电子邮件地址。

考虑到这一点,你可以通过以下步骤获得Gmail应用密码。注意,如果你使用的是现有账户,并启用了2步验证,你可以跳过第2和第3步。

  1. 创建或登录到Gmail账户
  2. 进入myaccount.google.com/lesssecurea…,打开不太安全的应用程序选项。
    Less secure apps
  3. 启用双因素认证,因为需要它来获取应用密码。
    2-factor-verification
  4. 现在你已经启用了双因素认证,是时候获得一个应用密码了。你可以通过进入你的谷歌账户的安全部分,向下滚动到登录谷歌部分,并点击应用密码来做到这一点。
    App password

你需要重新提示你的密码(账户密码),然后被转到应用密码页面。

一旦你进入,点击选择应用,在那里你将为该应用密码选择一个自定义名称--比如 "Django Send Email"--然后点击生成

App password generation

一个新的窗口将显示一个16个字符的密码。复制它,因为我们将需要它来配置我们的Django项目。

Generated app password

如果你使用的是其他电子邮件提供商,请务必阅读以下指南。

使用Django Environ来隐藏敏感的密钥

即使你只是在开发中发送电子邮件,你也不应该将密码直接写入源代码中。当与GitHub一起使用版本控制系统来托管你的项目时,这一点变得更加重要。你不希望别人访问你的数据。

让我们看看如何通过使用Django-environ来防止这种情况。

用下面的命令在EmailProject 目录下(settings.py 文件所在的位置)创建一个.env 文件。

cd EmailProject/
ls

settings.py # The settings file must be here

touch .env

现在,打开该.env 文件并输入以下键值对。

EMAIL_HOST=smtp.gmail.com
EMAIL_HOST_USER=YourEmail@address
EMAIL_HOST_PASSWORD=YourAppPassword
RECIPIENT_ADDRESS=TheRecieverOfTheMails

分解这个文件的内容。

  • EMAIL_HOST:你的电子邮件提供商的SMTP服务器地址。请看上面的电子邮件主机表以获得快速指导。在这种情况下,我使用smtp.gmail.com ,即Gmail的SMTP地址。
  • EMAIL_HOST_USER:你的电子邮件地址。
  • EMAIL_HOST_PASSWORD: 你刚刚生成的应用程序密码。请记住,它不包括任何空格。
  • RECIPIENT_ADDRESS: 你将收到信息的电子邮件地址。这是一个自定义的设置,我们将在后面创建,以将所有的邮件发送给同一个收件人。

为了利用这些环境变量,我们需要安装Django-environ

pip install django-environ

注意:确保你的虚拟环境被激活。

现在,打开位于EmailProject 目录下的settings.py ,使用下面的代码。

# EmailProject/settings.py
# This should be at the start of the file
import environ

env = environ.Env()
environ.Env.read_env()

# Previous settings ...
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = env('EMAIL_HOST')
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = env('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD')

# Custom setting. To email
RECIPIENT_ADDRESS = env('RECIPIENT_ADDRESS')

首先,我们要在设置文件的顶部导入environ 包。记住,所有的导入都应该在开头。

然后,我们创建一个env 变量,它将包含.env 上所有可用的键值对。

env('KEY') 语句意味着我们正在查找该键的值。在继续之前,请确保你已经设置了你的.env 文件,因为在某些环境变量没有设置的情况下,你会得到一个DjangoImproperlyConfigured 错误。

注意,RECIPIENT_ADDRESS 是一个自定义设置,我们将用它来发送邮件到一个我们可以访问的地址。

不要忘记在你的.gitignore中包含.env 文件,以防你使用Git和GitHub。你可以通过打开它并添加以下一行来完成。

.env

继续阅读《如何用Django发送邮件》,请点击SitePoint