如何通过Django发送电子邮件?

178

在我的settings.py文件中,我有以下内容:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

# Host for sending e-mail.
EMAIL_HOST = 'localhost'

# Port for sending e-mail.
EMAIL_PORT = 1025

# Optional SMTP authentication information for EMAIL_HOST.
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False

我的电子邮件代码:

from django.core.mail import EmailMessage
email = EmailMessage('Hello', 'World', to=['user@gmail.com'])
email.send()

当然,如果我通过 python -m smtpd -n -c DebuggingServer localhost:1025 设置调试服务器,我可以在终端中看到电子邮件。

但是,我该如何将电子邮件实际发送给 user@gmail.com 而不是调试服务器呢?

阅读了你们的答案后,让我澄清一些事情:

  1. 你不能使用本地主机(简单的Ubuntu PC)发送电子邮件吗?

  2. 我认为在django 1.3中,send_mail()有些被弃用了,而使用EmailMessage.send()代替?


3
  1. 如果您在本地运行SMTP服务器,那么您可以使用本地主机。
  2. 具体的机制并不重要,重要的是您拥有一个SMTP服务器。
- Ignacio Vazquez-Abrams
7
这个问题超出了本网站的范围。 - Ignacio Vazquez-Abrams
9
尽管如此,Ignacio,搜索引擎优化将我们带到了这个页面。 - Phlip
这个视频非常好地解释了所有必要的步骤。 - J0ANMM
不要认为使用第三方服务是“正确”的答案。它并不是。你可以安装像sendmail这样的 MTA,它将允许你在本地发送电子邮件。 - tread
显示剩余2条评论
13个回答

183

我在Django中使用Gmail作为我的SMTP服务器。这比处理postfix或其他服务器要容易得多。我不从事管理电子邮件服务器的业务。

在settings.py文件中:

EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'me@gmail.com'
EMAIL_HOST_PASSWORD = 'password'

注意:在2016年,Gmail默认不再允许此操作。您可以使用像Sendgrid这样的外部服务,或者按照谷歌的教程降低安全性以允许此选项:https://support.google.com/accounts/answer/6010255


8
留下明文密码有没有其他选择? - ritratt
31
将其放入环境变量中。然后,EMAIL_HOST_PASSWORD = os.environ['MY_PASSWORD_THAT_YOU_CANT_KNOW']。 - Drew Shafer
1
我完全使用了你的代码。几天后,我的Gmail帐户被封锁了。我的服务器可能每天发送的电子邮件少于20封。是否有人在使用Google时遇到过类似的问题? - eugene
1
谢谢!这节省了我很多时间 @Jordan - Thomas Gak-Deluen
8
SMTPAuthenticationError,我收到了一封邮件,内容为“阻止了登录尝试...来自不符合现代安全标准的应用程序”。 邮件看起来[像这样](http://i.stack.imgur.com/HdOwJ.png)。 解决方法是启用不太安全的应用程序访问权限,这样就可以解决问题了如此操作 - Bob Stein
显示剩余5条评论

65

将电子邮件发送到真正的SMTP服务器。 如果您不想设置自己的SMTP服务器,则可以找到可以为您运行SMTP服务器的公司,例如Google本身。


3
太棒了,我刚给自己发送了一封电子邮件!Miku提到的上面那篇文章非常完美。注意文章评论中的小错别字更正。(而且我只是使用了我的普通电脑/本地主机,之前没有设置任何其他东西。) - user984003
4
哪篇文章?你可以再提供一下链接吗? - CGFoX

55
  1. Create a project: django-admin.py startproject gmail
  2. Edit settings.py with code below:

    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_USE_TLS = True
    EMAIL_HOST = 'smtp.gmail.com'
    EMAIL_HOST_USER = 'youremail@gmail.com'
    EMAIL_HOST_PASSWORD = 'email_password'
    EMAIL_PORT = 587
    
  3. Run interactive mode: python manage.py shell

  4. Import the EmailMessage module:

    from django.core.mail import EmailMessage
    
  5. Send the email:

    email = EmailMessage('Subject', 'Body', to=['your@email.com'])
    email.send()
    

要了解更多信息,请查看documents中的send_mailEmailMessage功能。

Gmail更新

如果您无法通过Gmail发送电子邮件,请记得查看此指南,并在Google帐户设置中转到安全性>帐户权限>访问不太安全的应用程序并启用此选项。

在你 开启两步验证 后,需要为你的 Gmail 创建一个特定于应用程序的密码

然后在设置中使用 应用程序专用密码。所以更改以下行:

    EMAIL_HOST_PASSWORD = 'your_email_app_specific_password'

如果你有兴趣发送HTML邮件,看看这个


1
我按照你的步骤操作了,但无法发送邮件,收件人邮箱没有收到邮件。 - qg_java_17137
1
对于outlookoffice365,EMAIL_HOST将是什么? - Antu

18

如果上述解决方案在 Django 1.7 版本中无法工作,则尝试以下方法:

settings.py 文件中添加如下内容

#For email
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_USE_TLS = True

EMAIL_HOST = 'smtp.gmail.com'

EMAIL_HOST_USER = 'sender@gmail.com'

#Must generate specific password for your app in [gmail settings][1]
EMAIL_HOST_PASSWORD = 'app_specific_password'

EMAIL_PORT = 587

#This did the trick
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

最后一行对于Django 1.7起到了关键作用。


这个对我来说不起作用,原因不明。 我一直收到密码错误的错误。 这很奇怪,因为我直接从Mailgun获取了凭据。 - Alex Stewart

18

我的网站托管在Godaddy上,我还有一个私人电子邮件注册在同一处。 以下是适用于我的设置:

在settings.py中:

EMAIL_HOST = 'mail.domain.com'
EMAIL_HOST_USER = 'abc@domain.com'
EMAIL_HOST_PASSWORD = 'abcdef'
DEFAULT_FROM_EMAIL = 'abc@domain.com'
SERVER_EMAIL = 'abc@domain.com'
EMAIL_PORT = 25
EMAIL_USE_TLS = False

在shell中:

from django.core.mail import EmailMessage
email = EmailMessage('Subject', 'Body', to=['def@domain.com'])
email.send()

然后我得到了“1”作为输出,即成功。而且我也收到了邮件。:)

  • domain.com的意思是什么?

然后我得到了“1”作为输出,即成功。而且我也收到了邮件。:)

  • domain.com的意思是什么?

谢谢,这是在 Django 1.4 之前的旧项目中最简单的方法。 - François Constant

11

你需要在settings.py中使用smtp作为后端

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

如果您将后端作为控制台使用,您将在控制台中收到输出。
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

另外还有以下设置

EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'urusername@gmail.com'
EMAIL_HOST_PASSWORD = 'password'

如果您正在使用 Gmail,请设置“两步验证”和“应用程序专用密码”,并将该密码复制并粘贴到上面的 EMAIL_HOST_PASSWORD 值中。

5
我发现使用SendGrid是在Django中设置电子邮件发送最简单的方法。以下是它的工作方式:
  1. 创建SendGrid账户(并验证您的电子邮件)
  2. 将以下内容添加到您的settings.py文件中: EMAIL_HOST = 'smtp.sendgrid.net' EMAIL_HOST_USER = '<your sendgrid username>' EMAIL_HOST_PASSWORD = '<your sendgrid password>' EMAIL_PORT = 587 EMAIL_USE_TLS = True

这样就完成了!

要发送电子邮件:

from django.core.mail import send_mail
send_mail('<Your subject>', '<Your message>', 'from@example.com', ['to@example.com'])

如果您希望Django在出现500内部服务器错误时向您发送电子邮件,请将以下内容添加到您的settings.py文件中:
DEFAULT_FROM_EMAIL = 'your.email@example.com'
ADMINS = [('<Your name>', 'your.email@example.com')]

使用SendGrid发送邮件每月免费高达12k封。

1
很好,但是按照文档使用“apikey”作为用户名时无法使其工作,而SendGrid在一个简单的发送邮件功能上列出了三十多个apikey的权限配置... - SYK

4
你可以使用“Test Mail Server Tool”在你的机器或本地主机上测试电子邮件发送。请搜索并下载“Test Mail Server Tool”,然后设置它。

接着,在你的settings.py文件中:

EMAIL_BACKEND= 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 25

从shell:

from django.core.mail import send_mail
send_mail('subject','message','sender email',['receipient email'],    fail_silently=False)

3

我之前用Django做过这个。打开一个合法的Gmail账户并在这里输入凭据。这是我的代码 -

from email import Encoders
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart

def sendmail(to, subject, text, attach=[], mtype='html'):
    ok = True
    gmail_user = settings.EMAIL_HOST_USER
    gmail_pwd  = settings.EMAIL_HOST_PASSWORD

    msg = MIMEMultipart('alternative')

    msg['From']    = gmail_user
    msg['To']      = to
    msg['Cc']      = 'you@gmail.com'
    msg['Subject'] = subject

    msg.attach(MIMEText(text, mtype))

    for a in attach:
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(open(attach, 'rb').read())
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition','attachment; filename="%s"' % os.path.basename(a))
        msg.attach(part)

    try:
        mailServer = smtplib.SMTP("smtp.gmail.com", 687)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(gmail_user, gmail_pwd)
        mailServer.sendmail(gmail_user, [to,msg['Cc']], msg.as_string())
        mailServer.close()
    except:
        ok = False
    return ok

1
不需要直接使用smtplib;Django会为您处理这部分。 - Ignacio Vazquez-Abrams
哦,是吗!那该怎么办呢?在这里,我完全绕过默认的Django send_mail函数并使用自己的... - Srikar Appalaraju
1
send_mail() 是发送邮件的方法。你仍然需要自己组装邮件内容,但是不必担心 SMTP 部分。 - Ignacio Vazquez-Abrams

2

虽然有点晚了,但是:

除了其他人提到的DEFAULT_FROM_EMAIL修复方法,以及允许不太安全的应用程序访问该帐户之外,我还必须登录相关帐户,导航到https://accounts.google.com/DisplayUnlockCaptcha才能使Django最终进行身份验证。

我通过SSH隧道到Web服务器访问了该URL,以确保IP地址相同;我不确定这是否必要,但这样做不会有害。您可以这样做:ssh -D 8080 -fN <username>@<host>,然后将您的Web浏览器设置为使用localhost:8080作为SOCKS代理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接