尽管Python通过 smtplib
模块中,Django提供了几个轻量级的包装器。提供这些包装器是为了使发送电子邮件变得更加快速,帮助测试开发期间的电子邮件发送,并为无法使用RTP的平台提供支持。
代码存在于 django.core.mail
模块。
两条线:
from django.core.mail import send_mail
send_mail(
"Subject here",
"Here is the message.",
"from@example.com",
["to@example.com"],
fail_silently=False,
)
使用中指定的SMTP主机和端口发送邮件 EMAIL_HOST
和 EMAIL_PORT
设置。这个 EMAIL_HOST_USER
和 EMAIL_HOST_PASSWORD
设置(如果设置)用于对SMTP服务器进行身份验证,并且 EMAIL_USE_TLS
和 EMAIL_USE_SSL
设置控制是否使用安全连接。
备注
与一起发送的电子邮件的字符集 django.core.mail
将被设置为 DEFAULT_CHARSET
设置。
send_mail()
¶在大多数情况下,您可以使用发送电子邮件 django.core.mail.send_mail()
。
这个 subject
, message
, from_email
和 recipient_list
参数是必需的。
subject
一个字符串。
message
一个字符串。
from_email
:一根绳子。如果 None
,Django将使用 DEFAULT_FROM_EMAIL
布景。
recipient_list
:字符串列表,每个字符串都是电子邮件地址。每个成员 recipient_list
将在电子邮件的“收件人”字段中看到其他收件人。
fail_silently
一个布尔值。当它的时候 False
, send_mail()
将提高 smtplib.SMTPException
如果发生错误。见 smtplib
用于列出可能的异常的文档,所有这些异常都是 SMTPException
.
auth_user
:用于对SMTP服务器进行身份验证的可选用户名。如果没有提供,Django将使用 EMAIL_HOST_USER
设置。
auth_password
:用于对SMTP服务器进行身份验证的可选密码。如果没有提供,Django将使用 EMAIL_HOST_PASSWORD
设置。
connection
:用于发送邮件的可选电子邮件后端。如果未指定,将使用默认后端的实例。请参阅上的文档 Email backends 了解更多详细信息。
html_message
如果 html_message
如果提供,则生成的电子邮件将是 multipart/alternative 电子邮件与 message
作为 text/plain 内容类型和 html_message
作为 text/html 内容类型。
返回值将是成功传递的消息数(可以是 0
或 1
因为它只能发送一条消息)。
send_mass_mail()
¶django.core.mail.send_mass_mail()
旨在处理大量电子邮件。
datatuple
是一个元组,其中每个元素的格式如下:
(subject, message, from_email, recipient_list)
fail_silently
, auth_user
和 auth_password
具有与中相同的功能 send_mail()
.
每个单独的元素 datatuple
生成单独的电子邮件。如在 send_mail()
,收件人相同 recipient_list
将在电子邮件的“收件人:”字段中看到其他地址。
例如,以下代码将向两组不同的收件人发送两条不同的邮件;但是,只打开一个到邮件服务器的连接::
message1 = (
"Subject here",
"Here is the message",
"from@example.com",
["first@example.com", "other@example.com"],
)
message2 = (
"Another Subject",
"Here is another message",
"from@example.com",
["second@test.com"],
)
send_mass_mail((message1, message2), fail_silently=False)
返回值将是成功传递的消息数。
send_mass_mail()
vs. send_mail()
¶两者的主要区别 send_mass_mail()
和 send_mail()
那是 send_mail()
每次执行邮件服务器时都打开与邮件服务器的连接,同时 send_mass_mail()
对其所有消息使用单个连接。这使得 send_mass_mail()
效率略高。
mail_admins()
¶django.core.mail.mail_admins()
是向网站管理员发送电子邮件的快捷方式,如中定义的 ADMINS
设置。
mail_admins()
在主题前面加上 EMAIL_SUBJECT_PREFIX
设置,即 "[Django] "
默认情况下。
电子邮件的“发件人:”标题将是 SERVER_EMAIL
设置。
这种方法的存在是为了方便和可读性。
如果 html_message
如果提供,则生成的电子邮件将是 multipart/alternative 电子邮件与 message
作为 text/plain 内容类型和 html_message
作为 text/html 内容类型。
mail_managers()
¶django.core.mail.mail_managers()
就像是 mail_admins()
,除非它向站点经理发送电子邮件,如 MANAGERS
设置。
这将向john@example.com和jane@example.com发送一封电子邮件,两封邮件都显示在“收件人:”中:
send_mail(
"Subject",
"Message.",
"from@example.com",
["john@example.com", "jane@example.com"],
)
这会向john@example.com和jane@example.com发送一条消息,两人都会收到一封单独的电子邮件:
datatuple = (
("Subject", "Message.", "from@example.com", ["john@example.com"]),
("Subject", "Message.", "from@example.com", ["jane@example.com"]),
)
send_mass_mail(datatuple)
Header injection 是一种安全漏洞,攻击者在其中插入额外的电子邮件头来控制脚本生成的电子邮件消息中的“to:”和“from:”。
上面概述的django电子邮件功能通过禁止在头值中添加新行来防止头注入。如果有的话 subject
, from_email
或 recipient_list
包含新行(Unix、Windows或Mac样式)、电子邮件功能(例如 send_mail()
将提高 django.core.mail.BadHeaderError
(子类) ValueError
)因此,不会发送电子邮件。您有责任在将所有数据传递给电子邮件功能之前对其进行验证。
如果一个 message
字符串开头包含标题,则标题将打印为电子邮件的第一位。
下面是一个示例视图, subject
, message
和 from_email
从请求的post数据发送到admin@example.com,完成后重定向到“/contact/thanks/”:
from django.core.mail import BadHeaderError, send_mail
from django.http import HttpResponse, HttpResponseRedirect
def send_email(request):
subject = request.POST.get("subject", "")
message = request.POST.get("message", "")
from_email = request.POST.get("from_email", "")
if subject and message and from_email:
try:
send_mail(subject, message, from_email, ["admin@example.com"])
except BadHeaderError:
return HttpResponse("Invalid header found.")
return HttpResponseRedirect("/contact/thanks/")
else:
# In reality we'd use a form class
# to get proper validation errors.
return HttpResponse("Make sure all fields are entered and valid.")
EmailMessage
类¶贾戈 send_mail()
和 send_mass_mail()
函数实际上是利用 EmailMessage
类。
不是所有的功能 EmailMessage
课程可通过 send_mail()
以及相关的包装函数。如果要使用高级功能,如密件抄送收件人、文件附件或多部分电子邮件,则需要创建 EmailMessage
直接引用实例。
备注
这是一个设计特点。 send_mail()
相关函数最初是Django提供的唯一接口。然而,他们接受的参数列表随着时间的推移而缓慢增长。对于电子邮件来说,转向更面向对象的设计是有意义的,并且只保留原来的功能以实现向后兼容性。
EmailMessage
负责创建电子邮件本身。这个 email backend 然后负责发送电子邮件。
为了方便起见, EmailMessage
提供了一种 send()
发送单个电子邮件的方法。如果您需要发送多条消息,请使用电子邮件后台API provides an alternative 。
EmailMessage
对象¶这个 EmailMessage
类初始化时使用以下参数(如果使用位置参数,则按给定顺序)。所有参数都是可选的,可以在调用 send()
方法。
subject
:电子邮件的主题行。
body
:正文文本。这应该是一条纯文本消息。
from_email
:发件人地址。两个 fred@example.com
和 "Fred" <fred@example.com>
表格是合法的。如果省略, DEFAULT_FROM_EMAIL
使用设置。
to
:收件人地址的列表或元组。
bcc
:发送电子邮件时“bcc”头中使用的地址列表或元组。
connection
:电子邮件后端实例。如果要对多条消息使用同一连接,请使用此参数。如果省略,则当 send()
被称为。
attachments
:要放在消息上的附件列表。这些可以是 MIMEBase
实例,或具有属性的命名多元组 (filename, content, mimetype)
。
在旧版本中, attachments
是常规的二元组,而不是命名的二元组。
headers
:要放在消息上的额外头的字典。键是标题名称,值是标题值。由调用者来确保邮件头名称和值的格式正确。相应的属性是 extra_headers
.
cc
:发送电子邮件时“cc”头中使用的收件人地址列表或元组。
reply_to
:发送电子邮件时在“答复”标题中使用的收件人地址列表或元组。
例如::
from django.core.mail import EmailMessage
email = EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to1@example.com", "to2@example.com"],
["bcc@example.com"],
reply_to=["another@example.com"],
headers={"Message-ID": "foo"},
)
类具有以下方法:
send(fail_silently=False)
发送消息。如果在构建电子邮件时指定了连接,则将使用该连接。否则,将实例化并使用默认后端的一个实例。如果关键字参数 fail_silently
是 True
,则发送消息时引发的异常将被撤销。空的收件人列表不会引发异常。它会回来的 1
如果消息已成功发送,则为 0
。
message()
构建一个 django.core.mail.SafeMIMEText
对象(python的子类 MIMEText
类) django.core.mail.SafeMIMEMultipart
保存要发送的消息的对象。如果你需要延长 EmailMessage
类,您可能希望重写此方法以将所需内容放入mime对象。
recipients()
返回邮件的所有收件人的列表,无论他们是否记录在 to
, cc
或 bcc
属性。这是子类化时可能需要重写的另一种方法,因为在发送邮件时,需要告知SMTP服务器完整的收件人列表。如果添加另一种方法来指定类中的收件人,则还需要从此方法返回这些收件人。
attach()
创建新的文件附件并将其添加到邮件中。调用有两种方式 attach()
:
你可以给它传递一个单一的参数 MIMEBase
实例。这将直接插入到结果消息中。
或者,你可以通过 attach()
三个论点: filename
, content
和 mimetype
. filename
是将在电子邮件中显示的文件附件的名称, content
是将包含在附件中的数据,并且 mimetype
是附件的可选mime类型。如果省略 mimetype
,将根据附件的文件名猜测mime内容类型。
例如::
message.attach("design.png", img_data, "image/png")
如果指定 mimetype
的 message/rfc822 ,它也会接受 django.core.mail.EmailMessage
和 email.message.Message
。
为. mimetype
从开始 text/ ,内容预计为字符串。二进制数据将使用UTF-8进行解码,如果失败,则SME类型将更改为 application/octet-stream 并且数据将保持不变。
此外, message/rfc822 附件将不再使用base64编码,违反 RFC 2046#section-5.2.1 ,这可能会导致显示中的附件出现问题 Evolution and Thunderbird.
attach_file()
使用文件系统中的文件创建新附件。使用要附加的文件的路径来调用它,还可以使用要用于附件的SME类型。如果省略了MBE类型,则会从文件名中猜测出来。您可以这样使用它::
message.attach_file("/images/weather_map.png")
对于以开头的MBE类型 text/ ,二进制数据的处理方式如下 attach()
。
在电子邮件中包含多个版本的内容可能很有用;经典示例是发送消息的文本和HTML版本。通过Django的电子邮件库,您可以使用 EmailMultiAlternatives
班级。
的一个子类 EmailMessage
允许通过电子邮件中的消息正文的其他版本 attach_alternative()
法这直接从 EmailMessage
。
具有属性的命名二元组列表 (content, mimetype)
.这在测试中特别有用::
self.assertEqual(len(msg.alternatives), 1)
self.assertEqual(msg.alternatives[0].content, html_content)
self.assertEqual(msg.alternatives[0].mimetype, "text/html")
只能使用 attach_alternative()
方法。
在较旧的版本中, alternatives
是常规二元组列表,而不是命名二元组。
在电子邮件中附上消息正文的替代表示。
例如,要发送文本和HTML组合,您可以写::
from django.core.mail import EmailMultiAlternatives
subject = "hello"
from_email = "from@example.com"
to = "to@example.com"
text_content = "This is an important message."
html_content = "<p>This is an <strong>important</strong> message.</p>"
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
返回一个布尔值,指示所提供的 text
包含在电子邮件中 body
以及所有附加的MBE类型 text/*
替代品.
这在测试电子邮件时可能很有用。例如::
def test_contains_email_content(self):
subject = "Hello World"
from_email = "from@example.com"
to = "to@example.com"
msg = EmailMultiAlternatives(subject, "I am content.", from_email, [to])
msg.attach_alternative("<p>I am content.</p>", "text/html")
self.assertIs(msg.body_contains("I am content"), True)
self.assertIs(msg.body_contains("<p>I am content.</p>"), False)
默认情况下, body
AN中的参数 EmailMessage
是 "text/plain"
. 最好不要这样做,因为这样可以保证任何收件人都能够阅读电子邮件,而不管他们的邮件客户是谁。但是,如果您确信收件人可以处理其他内容类型,则可以使用 content_subtype
属性 EmailMessage
类以更改主要内容类型。主要类型将始终是 "text"
,但您可以更改子类型。例如::
msg = EmailMessage(subject, html_content, from_email, [to])
msg.content_subtype = "html" # Main content is now text/html
msg.send()
电子邮件的实际发送由电子邮件后端处理。
电子邮件后端类具有以下方法:
open()
实例化一个长期存在的电子邮件发送连接。
close()
关闭当前电子邮件发送连接。
send_messages(email_messages)
发送一个列表, EmailMessage
物体。如果连接未打开,则此调用将隐式打开连接,然后关闭连接。如果连接已打开,则在发送邮件后将保持打开状态。
它还可以用作上下文管理器,它将自动调用 open()
和 close()
根据需要:
from django.core import mail
with mail.get_connection() as connection:
mail.EmailMessage(
subject1,
body1,
from1,
[to1],
connection=connection,
).send()
mail.EmailMessage(
subject2,
body2,
from2,
[to2],
connection=connection,
).send()
这个 get_connection()
中的函数 django.core.mail
返回可以使用的电子邮件后端实例。
默认情况下,调用 get_connection()
将返回在中指定的电子邮件后端实例 EMAIL_BACKEND
. 如果您指定 backend
参数,将实例化该后端的实例。
这个 fail_silently
参数控制后端应如何处理错误。如果 fail_silently
为真,电子邮件发送过程中的异常将被静默忽略。
所有其他参数都直接传递给电子邮件后端的构造函数。
Django提供了几个电子邮件发送后端。除了SMTP后端(默认情况下),这些后端只在测试和开发期间有用。如果您有特殊的电子邮件发送要求,您可以 write your own email backend .
这是默认的后端。电子邮件将通过SMTP服务器发送。
如果参数为 None
:
host
: EMAIL_HOST
port
: EMAIL_PORT
username
: EMAIL_HOST_USER
password
: EMAIL_HOST_PASSWORD
use_tls
: EMAIL_USE_TLS
use_ssl
: EMAIL_USE_SSL
timeout
: EMAIL_TIMEOUT
ssl_keyfile
: EMAIL_SSL_KEYFILE
ssl_certfile
: EMAIL_SSL_CERTFILE
SMTP后端是Django继承的默认配置。如果要显式指定,请将以下内容放入设置中:
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
如果未指定,则默认 timeout
将由提供 socket.getdefaulttimeout()
,默认为 None
(没有超时时间)。
控制台后端不发送真实的电子邮件,只写将发送到标准输出的电子邮件。默认情况下,控制台后端写入 stdout
. 通过提供 stream
构造连接时使用关键字参数。
要指定此后端,请在设置中放置以下内容:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
这个后端并不打算用于生产——它是作为一种方便而提供的,可以在开发期间使用。
文件后端将电子邮件写入文件。将为此后端上打开的每个新会话创建一个新文件。将文件写入的目录可以从 EMAIL_FILE_PATH
设置或来自 file_path
创建连接时使用关键字 get_connection()
.
要指定此后端,请在设置中放置以下内容:
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = "/tmp/app-messages" # change this to a proper location
这个后端并不打算用于生产——它是作为一种方便而提供的,可以在开发期间使用。
这个 'locmem'
后端将消息存储在 django.core.mail
模块。这个 outbox
属性在发送第一条消息时创建。它是一个带有 EmailMessage
将发送的每个消息的实例。
要指定此后端,请在设置中放置以下内容:
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
这个后端并不打算用于生产——它是在开发和测试期间提供的一种方便。
顾名思义,虚拟后端与您的消息没有任何关系。要指定此后端,请在设置中放置以下内容:
EMAIL_BACKEND = "django.core.mail.backends.dummy.EmailBackend"
这个后端并不打算用于生产——它是作为一种方便而提供的,可以在开发期间使用。
如果您需要更改电子邮件的发送方式,您可以编写自己的电子邮件后端。这个 EMAIL_BACKEND
设置文件中的设置是后端类的python导入路径。
自定义电子邮件后端应子类 BaseEmailBackend
位于 django.core.mail.backends.base
模块。自定义电子邮件后端必须实现 send_messages(email_messages)
方法。此方法接收 EmailMessage
实例并返回成功传递的消息数。如果后端有任何持久会话或连接的概念,那么还应该实现 open()
和 close()
方法。参照 smtp.EmailBackend
用于引用实现。
建立和关闭一个SMTP连接(或任何其他网络连接,就这点而言)是一个昂贵的过程。如果你有很多邮件要发送,那么重新使用一个SMTP连接是有意义的,而不是每次你想发送邮件时都创建和破坏一个连接。
有两种方法可以告诉电子邮件后端重用连接。
首先,您可以使用 send_messages()
方法。 send_messages()
列出一个 EmailMessage
实例(或子类),并使用单个连接发送所有实例。
例如,如果有一个函数调用 get_notification_email()
返回一个列表 EmailMessage
对象表示您希望发送的某些定期电子邮件,您可以使用单个调用发送这些电子邮件以发送消息:
from django.core import mail
connection = mail.get_connection() # Use default email connection
messages = get_notification_email()
connection.send_messages(messages)
在本例中,调用 send_messages()
在后端打开连接,发送消息列表,然后再次关闭连接。
第二种方法是使用 open()
和 close()
方法在电子邮件后端手动控制连接。 send_messages()
如果连接已打开,则不会手动打开或关闭,因此如果手动打开连接,则可以控制连接关闭的时间。例如::
from django.core import mail
connection = mail.get_connection()
# Manually open the connection
connection.open()
# Construct an email message that uses the connection
email1 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to1@example.com"],
connection=connection,
)
email1.send() # Send the email
# Construct two more messages
email2 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to2@example.com"],
)
email3 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to3@example.com"],
)
# Send the two emails in a single call -
connection.send_messages([email2, email3])
# The connection was already open so send_messages() doesn't close it.
# We need to manually close the connection.
connection.close()
有时你根本不想让 Django 发送电子邮件。例如,在开发一个网站时,您可能不想发送数千封电子邮件,但您可能希望验证在正确的条件下将电子邮件发送给正确的人,并且这些电子邮件将包含正确的内容。
为本地开发配置电子邮件的最简单方法是使用 console 电子邮件后端。此后端会将所有电子邮件重定向到 stdout
,允许您检查邮件内容。
这个 file 电子邮件后端在开发过程中也很有用——这个后端将每个SMTP连接的内容转储到一个可以在空闲时检查的文件中。
另一种方法是使用“愚蠢的”SMTP服务器,它在本地接收电子邮件并将它们显示给终端,但实际上并不发送任何东西。这个 aiosmtpd Package提供了一种实现这一点的方法:
python -m pip install aiosmtpd
python -m aiosmtpd -n -l localhost:8025
此命令将启动侦听本地主机的端口8025的最小SMTP服务器。此服务器将所有电子邮件标题和电子邮件正文打印到标准输出。然后,您只需将 EMAIL_HOST
和 EMAIL_PORT
相应地。有关SMTP服务器选项的更详细讨论,请参阅 aiosmtpd 模块。
有关在应用程序中测试电子邮件发送的单元的信息,请参阅 电子邮件服务 测试文件的章节。
7月 22, 2024