Django send_mail报idna编码错误:label empty or too long求助
问题描述
在使用Django的send_mail函数发送邮件时,出现错误提示:encoding with 'idna' codec failed (UnicodeError: label empty or too long)。该功能在另一台电脑上可正常运行,已排除settings.py配置问题,尝试使用idna库后仍报错,求问题原因及正确编码解决办法。
相关代码
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST_USER = 'my_mail@gmail.com' EMAIL_HOST_PASSWORD = 'my_password' EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_USE_SSL = False
views.py
def post_share(request, slug): post = get_object_or_404(Post, slug=slug, status='published') sent = False form = EmailPostForm(request.POST or None) if request.method == "POST" and form.is_valid(): cd = form.cleaned_data post_url = request.build_absolute_uri(post.get_absolute_url()) name_user = cd["email"].replace("@gmail.com", "") subject = f'Пользователь ({name_user}) рекомендует к прочтению — {post.title}' message = f'Прочитайте "{post.title}" по ссылке - {post_url}\n\nСообщение: {cd["comments"]}' send_mail(subject, message, settings.EMAIL_HOST_USER, [cd['to']]) sent = True return render(request, 'blog/post/share.html', {'post': post, 'form': form, 'sent': sent})
问题原因及解决办法
原因
错误根源是邮件主题/内容中的俄文属于非ASCII字符,Django默认的邮件编码处理逻辑无法正确适配,导致SMTP协议在执行IDNA编码时失败。
解决办法
1. 显式指定编码调用send_mail
修改send_mail的调用,添加encoding='utf-8'参数,强制使用UTF-8编码处理非ASCII字符:
send_mail(subject, message, settings.EMAIL_HOST_USER, [cd['to']], encoding='utf-8')
2. 用Header类编码邮件主题
如果上述方法无效,使用Django提供的Header类对主题进行标准编码,确保符合邮件传输规范:
首先导入Header:
from django.core.mail import Header
然后重构主题代码:
subject = Header(f'Пользователь ({name_user}) рекомендует к прочтению — {post.title}', 'utf-8').encode()
3. 排查收件人邮箱格式
确认cd['to']是合法的邮箱地址,避免空值或格式错误(虽然表单校验已处理,但额外排查可排除潜在问题)。
4. 检查本地环境编码(Python 2适用)
如果使用Python 2,检查本地默认编码是否为UTF-8,若不是,在项目入口文件(如manage.py)添加:
import sys reload(sys) sys.setdefaultencoding('utf-8')
Python 3默认编码为UTF-8,无需此操作。
内容的提问来源于stack exchange,提问作者user21458350
相关产品推荐
相关产品推荐

