Django生产环境下添加邮件附件出现500错误求助
解决Django生产环境中静态文件作为邮件附件发送的500错误
先梳理下你代码里的几个关键问题,这大概率是触发生产环境500错误的核心原因:
1. 路径拼接写法错误
你当前用的os.path.join(settings.STATIC_ROOT+'/attachment/test.pdf')是错误的用法——os.path.join的设计初衷是接收多个路径片段参数,自动处理不同系统的路径分隔符,而你把完整路径字符串塞进去,完全浪费了它的优势,还可能因为多余斜杠导致路径解析异常。
正确的路径拼接方式应该是:
file_path = os.path.join(settings.STATIC_ROOT, 'attachment', 'test.pdf')
这种写法不管是Linux还是Windows系统,都会自动生成合规的路径,避免手动拼接斜杠带来的低级错误。
2. add_attachment参数顺序搞反了
Django的EmailMessage.add_attachment()方法参数顺序是二进制内容、MIME类型、文件名,你现在把文件名放在了第一个位置,这会导致邮件附件的内容被错误设置成字符串'test.pdf',而非文件的二进制数据,直接引发异常。
正确的调用方式(推荐用关键字参数,避免顺序混淆):
msg.add_attachment( content=data, mimetype='application/pdf', filename='test.pdf' )
3. 生产环境文件权限检查
如果上面的修正后还是报错,一定要检查生产服务器上静态文件的权限:
- 确保运行Django应用的进程用户(比如gunicorn的运行用户、www-data等)有读取
/home/project/project/static_files/attachment/test.pdf的权限 - 可以用
ls -l /home/project/project/static_files/attachment/test.pdf查看权限,确保其他用户有读权限(比如权限为-rw-r--r--),如果没有,执行chmod 644 /home/project/project/static_files/attachment/test.pdf修改权限
修正后的完整代码示例
if form.is_valid(): file_path = os.path.join(settings.STATIC_ROOT, 'attachment', 'test.pdf') try: msg = EmailMessage('subject', 'body', 'sender@example.com', ['recipient@example.com']) with open(file_path, 'rb') as attach_file: data = attach_file.read() msg.add_attachment(content=data, mimetype='application/pdf', filename='test.pdf') msg.send() # 这里可以添加发送成功后的逻辑,比如重定向或用户提示 except Exception as e: # 生产环境建议捕获异常并记录日志,方便排查问题 import logging logger = logging.getLogger(__name__) logger.error(f"发送邮件附件失败: {str(e)}") # 返回错误响应给用户
另外,开发环境能成功可能是因为开发服务器的运行用户是你自己,权限足够,而且路径拼接的小错误在本地环境不会触发异常,但到Linux生产服务器就暴露出来了。
内容的提问来源于stack exchange,提问作者horse
相关产品推荐
相关产品推荐

