Django邮件发送失败:设置端口587却自动使用25端口
问题
我的Django项目目前无法发送邮件,3个月前代码运行完全正常。
配置信息(settings.py)
DEBUG = True EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT: 587 EMAIL_HOST_USER = 'xyz@gmail.com' EMAIL_HOST_PASSWORD = 'xyz' EMAIL_USE_TLS = True ALLOWED_HOSTS = []
视图代码(views.py)
def index(request): """The home page.""" # Send a message. if request.method != 'POST': # No data submitted; create a blank form. form_email = EmailForm() form_message = EmailMessageForm() else: # POST data submitted; proecess data. form_email = EmailForm(data=request.POST) form_message = EmailMessageForm(data=request.POST) if form_email.is_valid() and form_message.is_valid(): try: email = Email.objects.get(text=request.POST['text']) except: form_email.save() email = Email.objects.last() message_db = form_message.save(commit=False) message_db.email = email message_db.save() message_owner = ( f'New email on your website from {request.POST["text"]}', f"Email has been sent from: {request.POST['text']}\n\n" f"Full message:\n\"{request.POST['message']}\"", 'settings.EMAIL_HOST_USER', ['my@gmail.com',], ) message_guest = ('Your email has been sent', "Many thanks for getting in contact with me. Your message was " "successfully sent. I will reach out to you as soon as possible." f"\n\nYour message:\n\"{request.POST['message']}\"", 'settings.EMAIL_HOST_USER', [request.POST['text'],], ) send_mass_mail((message_owner, message_guest), fail_silently=False) return redirect('home:contact_thank_you') # Display a blank or invalid form. context = {'form_email': form_email, 'form_message': form_message} return render(request, 'home/index.html', context)
报错信息
请求方法:POST
请求URL:http://127.0.0.1:8000/
Django版本:4.1.5
异常类型:TimeoutError
异常信息:[WinError 10060] 由于连接方在一段时间后没有正确响应或连接的主机没有反应,连接尝试失败
触发位置:home.views.index
核心疑问:明明在settings.py里设置了端口为587,但实际发送时却使用默认的25端口,为什么配置没生效?该怎么解决?
解决方法
1. 修复settings.py的语法错误
EMAIL_PORT: 587使用了冒号,这是Python字典语法,不是变量赋值,Django无法识别这个配置,因此会 fallback 到默认端口25。把冒号改成等号即可:
EMAIL_PORT = 587
2. 修正视图中的发件人参数
视图里的message_owner和message_guest中,发件人写的是字符串'settings.EMAIL_HOST_USER',这会被当成字面量邮箱地址,而非读取配置里的真实邮箱。需要先导入settings模块,再引用变量:
# 在views.py顶部添加导入语句 from django.conf import settings # 修改消息的发件人部分,去掉引号 message_owner = ( f'New email on your website from {request.POST["text"]}', f"Email has been sent from: {request.POST['text']}\n\n" f"Full message:\n\"{request.POST['message']}\"", settings.EMAIL_HOST_USER, ['my@gmail.com',], ) message_guest = ('Your email has been sent', "Many thanks for getting in contact with me. Your message was " "successfully sent. I will reach out to you as soon as possible." f"\n\nYour message:\n\"{request.POST['message']}\"", settings.EMAIL_HOST_USER, [request.POST['text'],], )
3. 检查Gmail的SMTP权限设置
当前Gmail默认禁用普通密码登录SMTP,需要根据账号状态调整:
- 若开启了两步验证:生成应用专用密码,替换settings里的
EMAIL_HOST_PASSWORD。 - 若未开启两步验证:需开启“不太安全的应用访问”(不推荐,建议优先开启两步验证后使用应用专用密码)。
4. 测试SMTP连接可用性
可以用Python自带的smtplib测试端口587的连接情况,排查网络或权限问题:
import smtplib try: server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login('xyz@gmail.com', '你的应用专用密码') print("SMTP连接成功") server.quit() except Exception as e: print(f"连接失败: {e}")
内容的提问来源于stack exchange,提问作者Maxwell
相关产品推荐
相关产品推荐

