Django条件发送邮件附加PDF时遇文件不存在错误求助
解决Django邮件附件"File does not exist"问题
别着急,这是新手用Django处理文件路径时很容易踩的坑,我来帮你理清问题所在:
为什么会出现这个错误?
你直接用attach_file('eradicate/LCHF Eradicate Diabetes.pdf')这种相对路径时,Django是从项目运行的工作目录去查找文件,而不是你的eradicateapp目录。比如你在项目根目录执行python manage.py runserver,理论上这个路径是对的,但为什么一个文件能找到另一个不行?大概率是文件名细节(比如空格、大小写)的隐形差异,或者相对路径在不同场景下的解析不稳定——而绝对路径能彻底解决这个问题。
另外你看到的eradicate\\LCHF Eradicate Diabetes.pdf里的双反斜杠是Windows系统的路径表示(Python会把单个反斜杠转义成两个),这本身不是错误,只是路径的显示方式。
正确解决方案:使用绝对路径
Django提供了settings.BASE_DIR变量,它指向你的项目根目录,我们可以用它拼接出PDF文件的绝对路径,这样无论工作目录是什么,都能精准找到文件。
步骤1:导入必要模块
在你的视图文件顶部加上:
import os from django.conf import settings
步骤2:重构附件路径逻辑
把原来的attach_file部分改成下面的代码:
# 获取eradicate app的绝对路径 eradicate_dir = os.path.join(settings.BASE_DIR, 'eradicate') if patienthist.foodhabit == 'N': pdf_path = os.path.join(eradicate_dir, 'LCHF Eradicate Diabetes.pdf') else: pdf_path = os.path.join(eradicate_dir, 'LFV Eradicate Diabetes.pdf') # 附加文件 msg.attach_file(pdf_path)
更规范的文件存储建议
虽然把PDF放在app根目录能工作,但更符合Django规范的做法是:
- 在
eradicateapp下创建static/eradicate/pdfs目录 - 把你的PDF文件移到这个目录里
- 用
BASE_DIR拼接路径:
pdf_path = os.path.join(settings.BASE_DIR, 'eradicate', 'static', 'eradicate', 'pdfs', 'LCHF Eradicate Diabetes.pdf')
这样做的好处是:方便和其他静态资源一起管理,部署时更容易用collectstatic命令统一收集静态文件。
最后检查点
- 确认PDF文件名的拼写、空格、大小写完全一致,Windows虽然大小写不敏感,但Python的路径解析有时候会严格匹配
- 可以打印
pdf_path变量,然后去文件管理器里核对路径是否正确
内容的提问来源于stack exchange,提问作者MRM
相关产品推荐
相关产品推荐

