转自:https://django-chinese-docs-14.readthedocs.org/en/latest/topics/email.html
尽管Python已经提供了相对易用的邮件发送模块 smtplib ,但Django仍对其做了轻度的封装。封装后的模块不仅发送邮件速度快,而且在开发环境下也很容易对邮件发送进行测试,
并对无法使用SMTP的平台也提供了支持。
封装代码在 django.core.mail 模块中。
入门例子
只有两行:
Django发邮件功能要用到配置文件中的 EMAIL_HOST 和 EMAIL_PORT 配置项,分别用来指定发邮件服务器和端口。
如果SMTP服务器需要用户认证,还须设置 EMAIL_HOST_USER 和 EMAIL_HOST_PASSWORD 配置项,指定用户名和密码。
而EMAIL_USE_TLS 配置项则决定是否使用安全加密链接。
Note
由 django.core.mail 发送的邮件,其字符集都由 DEFAULT_CHARSET 配置项决定。
send_mail()
- send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None,auth_password=None, connection=None)
发邮件的最便捷方式就是使用 django.core.mail.send_mail() 。
subject, message, from_email and recipient_list 这四个参数是必须的。
- subject: 字符串,表示邮件标题。
- message: 字符串,表示邮件内容。
- from_email: 字符串,表示发件邮箱。
- recipient_list: 字符串列表,列表中每个成员都是一个邮箱地址,而且每个收件人都会在 “收件人/To:” 栏看到出现在 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: (可选)发送邮件的后端。没提供该参数的情况下,Django会使用默认后端的实例。可查看 Email
backends 了解更多细节。
send_mass_mail()
- send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None,connection=None)
django.core.mail.send_mass_mail() 适合处理群发邮件。
datatuple 是一个元组,其中每个元素格式如下:
fail_silently, auth_user 和 auth_password 与上面 send_mail() 中提到的一样。
datatuple 中每个元素都对应一封单独的邮件。与上面 send_mail() 一样,出现在 recipient_list 中的收件人同样会在
“收件人/To:” 字段中看到该邮件的其他所有收件人。
举个例子,下面的代码会给双组不同的收件人发送两封不同的邮件;但仅仅打开一次邮件服务器的链接:
send_mass_mail() vs. send_mail()
send_mass_mail() 和 send_mail() 的区别在于: send_mail() 每发送一封邮件就会打开一次邮件服务器链接,而send_mass_mail() 则是打开一次链接,发送所有的邮件。 send_mass_mail() 明显更高效。
mail_admins()
- mail_admins(subject, message, fail_silently=False, connection=None, html_message=None)
django.core.mail.mail_admins() 是一个给网站后台管理员(admin)发邮件的快捷方法,管理员设置放在 ADMINS 配置项。
mail_admins() 使用 EMAIL_SUBJECT_PREFIX 配置项的值做为邮件标题的前缀,默认情况下是 "[Django] " 。
邮件的”From:”头的内容就是 SERVER_EMAIL 配置项的值。
该方法方便使用且易于理解。
see the release notes
如果提供了 html_message 参数,会导致邮件变成 multipart/alternative , message 格式变成 text/plain ,html_message 格式变成 text/html 。
mail_managers()
- mail_managers(subject, message, fail_silently=False, connection=None,html_message=None)
django.core.mail.mail_managers() is just like mail_admins() ,不同之处在于该方法的邮件接收人是网站负责人(manager),
可以在 MANAGERS 配置项设置网站负责人。
例子
该例同时给 john@example.com 和 jane@example.com 发送同一封邮件,这两个邮箱地址都会出现在
“收件人/To:” 一栏:
该例则是分别为 john@example.com 和 jane@example.com 分别发送同一封邮件,每人收到的邮件只显示唯一一个收件人:
防止邮件头注入
Header injection (邮件头信息注入)是可以被骇客(黑客hacker是指伟大的程序员,骇客Cracker和Attacker是指无知无耻的狗盗之辈)利用的安全漏洞。 他们会利用该漏洞,在代码生成的邮件报文中添加额外的邮件头信息(header)以控制
“收件人/To:” 和 “发件人/From:” 。
之前所提及的Django邮件函式都禁止在头信息中添加换行,从而避免注入。只要 subject , from_email 和recipient_list 包含换行(不管是Windows格式,还是Unix或是Mac
OS 格式) ,发送函式 (比如 send_mail())
都会抛出 django.core.mail.BadHeaderError 异常( ValueError 的一个子类),也不会发送该邮件。
因此在给邮件函式传递参数之前,一定要对所有数据进行验证。
如果 message 在文本最开始处含有头信息,那么这些头信息就会被打印成邮件内容的第一个比特。
下面这个view例子, subject , message 和 from_email 从request
POST中取值,然后发送邮件到admin@example.com, 发送成功后重定向到”/contact/thanks/”:
EmailMessage类
Django的 send_mail() 和 send_mass_mail() 函式事实上是对 EmailMessage 类使用方式
的一个轻度封装。
send_mail() 和相关的其他封装函式并没有充分使用 EmailMessage 类的所有特性。
要想使用更多特性,比如暗送(BCC)给收件人,加入附件,或是多用途格式(multi-part)邮件,都要直接创建 EmailMessage 实例。
Note
这是一个设计特性: send_mail() 和其他相关函式是最初只是由Django提供的一组接口。
但是其接收的参数数量却随着Django的发展而慢慢增长。这样就能理解为什么要将邮件报文使用面向对象设计重新设计,同时又保留原有函式以保证后端兼容,
EmailMessage 仅仅负责创建邮件报文,而 email
backend 则负责邮件发送。
为了方便起见, EmailMessage 提供了一个简单的 send() 方法用以发送纯文本邮件。如果想发送多用途格式邮件,可以使用后端API 发送多用途邮件.
EmailMessage 对象
- class EmailMessage
EmailMessage 类使用下列参数初始化(除非使用位置参数,否则默认顺序如下)。所有参数均可选,均可在调用 send()方法之前的任何时间对其赋值。
- subject: 邮件的标题行
- body: 邮件的主体内容文本,须是纯文本信息。
- from_email: 发送者的地址。 fred@example.com 或 Fred <fred@example.com> 格式都是合法的。如果忽略该参数,Django就会使用 DEFAULT_FROM_EMAIL 配置项。
- to: 收件人地址列表或元组。
- bcc: 发送邮件时用于”Bcc”头信息的一组列表或元组,也就是暗送的收件人。
- connection: 一个邮件后端实例。用同一个链接发送多封邮件就要用到该参数。忽略该参数时,会在调用 send() 时自动创建一个新链接。
- attachments: 置于邮件报文内的附件列表。列表元素可以是 email.MIMEBase.MIMEBase 实例,也可以是(filename, content, mimetype) 三部分构成的元组。
- headers: 置于邮件报文内的其他头信息(header)的字典。字典的key是头信息的名称,字典的value是头信息的值。 这样做能确保头信息的名称和对应值会以正确的格式保存于邮件报文中。
- cc: 发送邮件时放于”Cc”头信息的一系列列表或元组。
例如:
该类方法如下:
-
send(fail_silently=False) 发送邮件报文。如果在构造邮件时如果指定了某个链接(connection),就会使用该链接发邮件。 否则,就会使用默认后端的实例发邮件。如果关键字参数 fail_silently 为 True ,就会忽略邮件发送时抛出的异常。
-
message() 构造了一个 django.core.mail.SafeMIMEText 对象 (Python的 email.MIMEText.MIMEText 类的子类)
或是 django.core.mail.SafeMIMEMultipart 对象(该对象保存即将发送出去邮件报文)。如需扩展 EmailMessage类,一般情况下要覆写该方法,将你所需的内容添加到MIME对象中。 -
recipients() 返回邮件中所有收件人的列表,不管收件人是在 to 还是 bcc 属性中。这是另一个经常被继承覆写的方法,
因为SMTP服务器在发送邮件报文时,要接收完整的收件人列表。即使你自己的类使用其他方式来指定收件人,也仍然需要使用该方法返回收件人列表。 -
attach() 创建一个新的文件附件,并把它添加到邮件报文中。 有两种方法调用 attach():
-
传递一个单独的 email.MIMEBase.MIMEBase 实例做为参数。该实例会直接添加到最终的邮件报文中。
-
或者,给 attach() 传递三个参数: filename, content 和 mimetype. filename 是出现在邮件中的附件文件的名称, content 是附件的内容,而 mimetype 是附件所使用的MIME类型。
如果忽略 mimetype, Django会自动根据附件文件名来推测MIME内容类型。例如:
-
-
attach_file() 使用当前文件系统下的某个文件做为附件。调用时,传入某个文件的完整路径,以及该附件的MIME类型(可选的)。 忽略MIME类型的话,Django会自动根据附件文件名来推测MIME类型。最简单的用法如下: