You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django send_mail调用失败但smtplib正常的问题排查

问题:Django send_mail连接Gmail SMTP时触发SMTPServerDisconnected错误

使用Django的send_mail函数,通过开启双重验证的Gmail账户(使用应用专用密码)发送邮件时,出现smtplib.SMTPServerDisconnected: Connection unexpectedly closed错误,但直接用smtplib编写的脚本却能正常发送邮件。


排查过程与问题根源

  • 编辑1:移除django/core/mail/backends/smtp.py第81行中传递给self.connection_class的**connection_params参数后,send_mail可正常工作。
  • 编辑2:将手动smtplib脚本中的smtpObj = smtplib.SMTP('smtp-relay.gmail.com', 587)改为smtpObj = smtplib.SMTP('smtp-relay.gmail.com', 587, local_hostname='localhost')后,会触发相同的连接断开错误。
  • 编辑3:问题核心在于django/core/mail/backends/smtp.py第69行,代码硬编码将connection_params赋值为{"local_hostname": DNS_NAME.get_fqdn()},且未提供自定义或清空该参数的逻辑。而DNS_NAME.get_fqdn()调用socket.getfqdn()返回未完全限定的localhost,smtplib会将其替换为127.0.0.1,这属于Django的一处Bug。

相关代码片段

settings.py

...
EMAIL_HOST = 'smtp-relay.gmail.com' 
EMAIL_HOST_USER = "myemail@costumgmail.com" 
EMAIL_HOST_PASSWORD = "mypass" 
EMAIL_PORT = 587 
EMAIL_USE_TLS = True
...

djangotest.py

from django.core.mail import send_mail
send_mail('Django mail', 'This e-mail was sent with Django.', "myemail@costumgmail.com" , ['some.other@mail.com'], fail_silently=False)
# 触发错误:smtplib.SMTPServerDisconnected: Connection unexpectedly closed

smtplibtest.py

from email.message import EmailMessage
import smtplib

email_sender = "myemail@costumgmail.com" 
email_password="mypass"
email_reciever ='some.other@mail.com'

subject = "test"
body = "test"
em = EmailMessage()
em['sender'] = email_sender
em['to'] = email_reciever
em['subject'] = subject
em.set_content(body)

smtpObj = smtplib.SMTP('smtp-relay.gmail.com', 587)
smtpObj.ehlo() # 返回:(250, b'smtp-relay.gmail.com at your service, [188.26.233.149]\nSIZE 157286400\n8BITMIME\nSTARTTLS\nENHANCEDSTATUSCODES\nPIPELINING\nCHUNKING\nSMTPUTF8')

smtpObj.starttls() # 返回:(220, b'2.0.0 Ready to start TLS')

smtpObj.login(email_sender, email_password) # 返回:(235, b'2.7.0 Accepted')

smtpObj.sendmail(email_sender, email_reciever, em.as_string()) # 发送成功

Django报错栈

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/__init__.py", line 87, in send_mail
    return mail.send()
  File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/message.py", line 298, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 124, in send_messages
    new_conn_created = self.open()
  File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 87, in open
    self.connection.starttls(
  File "/usr/lib/python3.10/smtplib.py", line 769, in starttls
    self.ehlo_or_helo_if_needed()
  File "/usr/lib/python3.10/smtplib.py", line 612, in ehlo_or_helo_if_needed
    (code, resp) = self.helo()
  File "/usr/lib/python3.10/smtplib.py", line 441, in helo
    (code, msg) = self.getreply()
  File "/usr/lib/python3.10/smtplib.py", line 405, in getreply
    raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed

内容的提问来源于stack exchange,提问作者Petru Tanas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:31:12