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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:55:09