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

Django3中名称超75字符的邮件因sanitize_address发送失败如何解决

Django 3 发送名称超过75字符邮件的解决方案

问题核心

Django 3版本中django/core/mail/message.py下的sanitize_address()方法存在已知缺陷:地址名称部分通过email.header.Header.encode()方法编码时,会默认在字符数达到75时自动插入换行符,导致邮件地址格式异常,最终无法成功发送邮件。

可落地实现方案

方案一:猴子补丁全局替换(改动最小,生效最快)

直接在项目启动时替换Django原生的sanitize_address方法,修改Header的最大行长度限制,避免自动换行:

  1. 在项目根目录下新建patches/email_patch.py文件,写入以下代码:
from django.core.mail import message
from email.header import Header

def patched_sanitize_address(addr, encoding):
    if isinstance(addr, str):
        return addr
    name, addr_val = addr
    if not name:
        return addr_val
    # 调整最大行长度为1000,覆盖默认75字符的换行限制
    name_encoded = Header(name, encoding, maxlinelen=1000).encode()
    return f"{name_encoded} <{addr_val}>"

# 覆盖原生方法
message.sanitize_address = patched_sanitize_address
  1. 在项目根目录的__init__.py中导入补丁,确保项目启动时自动加载:
from patches.email_patch import patched_sanitize_address
  • 方案优势:无需修改原有业务邮件发送代码,全量兼容现有逻辑,适合需要快速修复的场景。

方案二:自定义SMTP邮件后端(无侵入,更安全)

如果不想全局修改Django底层方法,可以自定义邮件后端,单独处理地址格式化逻辑:

  1. 在项目下新建backends/custom_email_backend.py文件,写入以下代码:
from django.core.mail.backends.smtp import EmailBackend
from email.headerregistry import Address

class LongAddressEmailBackend(EmailBackend):
    def format_single_address(self, addr_pair):
        name, email_addr = addr_pair
        if not name:
            return email_addr
        # 使用Python 3原生的Address类处理,不存在自动换行问题
        return str(Address(display_name=name, addr_spec=email_addr))

    def _send(self, email_message):
        # 格式化所有邮件地址字段
        if isinstance(email_message.from_email, (list, tuple)):
            email_message.from_email = self.format_single_address(email_message.from_email)
        email_message.to = [self.format_single_address(addr) if isinstance(addr, (list, tuple)) else addr for addr in email_message.to]
        email_message.cc = [self.format_single_address(addr) if isinstance(addr, (list, tuple)) else addr for addr in email_message.cc]
        email_message.bcc = [self.format_single_address(addr) if isinstance(addr, (list, tuple)) else addr for addr in email_message.bcc]
        email_message.reply_to = [self.format_single_address(addr) if isinstance(addr, (list, tuple)) else addr for addr in email_message.reply_to]
        return super()._send(email_message)
  1. 在settings.py中修改邮件后端配置:
EMAIL_BACKEND = 'backends.custom_email_backend.LongAddressEmailBackend'
  • 方案优势:不会修改Django全局方法,升级Django版本时无兼容风险,适合对代码规范性要求较高的场景。

方案三:升级Django版本(长期最优解)

该问题已经在Django 3.2.10及更高的3.2系列版本、以及所有4.x版本中修复,如果业务允许升级框架版本,直接升级到对应版本即可彻底解决问题,无需额外代码修改。


内容的提问来源于stack exchange,提问作者Nicolás Gustavo Bruna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 04:15:08