Django使用EmailMessage发送波斯语邮件时编码错误求助
刚接触Django,尝试使用django.core.mail.EmailMessage发送包含波斯语字符的邮件,代码如下:
from django.core.mail import EmailMessage from django.conf import settings def custom_sender(subject: str, body: str, recipient_list: list[str], attachments: list[str] = (), content_type_html: bool = False): try: email = EmailMessage( subject, body, settings.DEFAULT_FROM_EMAIL, recipient_list, ) if content_type_html: email.content_subtype = "html" for attachment in attachments: email.attach_file(attachment) email.send() except Exception as e: print(f'\n\nFailed to send email: {e}\n\n')
视图中调用方式:
custom_sender(subject='ایمیل تستی', body='این یک ایمیل تستی است.', recipient_list=[user.email])
遇到错误:'charmap' codec can't encode character '\u06cc' in position 1: character maps to <undefined>
同时发现Django项目内无法在控制台打印波斯语内容,会出现相同错误(项目外可正常打印)。尝试过对主题和正文用.encode('utf-8')编码、使用Django的smart_str、Python的Unicode字符串格式,修改settings.py(调整DEFAULT_CHARSET、默认语言为波斯语,DEFAULT_CHARSET原本就是'utf-8'),均无效。
运行环境:Windows 10、Python 3.12、Django 5.0
问题根源在于Windows系统默认控制台编码为GBK(即charmap),Python在Windows环境下运行时,标准输出/错误流默认继承该编码。当处理波斯语这类不在GBK编码范围内的Unicode字符时,无论是控制台打印还是异常信息输出,都会触发编码失败。邮件发送的错误实际是异常捕获中的print语句尝试输出含波斯语的信息导致,而非邮件本身的编码逻辑问题。
1. 修复控制台编码问题
方法一:修改项目入口文件
在manage.py开头添加以下代码,强制Python标准输出/错误流使用UTF-8编码:
import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='utf-8') sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding='utf-8')
方法二:切换控制台编码
运行Django项目前,在Windows控制台执行以下命令切换编码为UTF-8:
chcp 65001
2. 显式指定邮件编码
修改custom_sender函数,创建EmailMessage时显式指定UTF-8编码,消除潜在编码歧义:
email = EmailMessage( subject, body, settings.DEFAULT_FROM_EMAIL, recipient_list, charset='utf-8' # 显式声明UTF-8编码 )
若发送HTML邮件,需在HTML内容的<head>中添加编码声明:
<meta charset="UTF-8">
3. 替换异常中的print语句(可选)
避免控制台编码限制,改用日志记录错误信息:
import logging logger = logging.getLogger(__name__) # 替换原有print语句 logger.error(f'Failed to send email: {e}')
在settings.py中配置日志输出到文件,即可正常记录包含特殊字符的错误信息。
内容的提问来源于stack exchange,提问作者confused coder

