Django发送含图片邮件失败,排查问题原因
问题分析与解决方案
核心问题
本地浏览器能显示图片是因为它能直接访问你的本地开发服务器,但邮件客户端处于外部网络,无法访问localhost这类本地地址;同时你的静态文件配置存在错误,导致生产环境下静态资源无法被正确访问。
具体修复步骤
1. 修正静态文件配置
你的STATIC_ROOT配置错误,它应该指向项目内用于收集静态文件的目录,而非根目录的/static/:
STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'app/static/img') ]
修改后运行python manage.py collectstatic,将所有静态文件收集到STATIC_ROOT目录,确保部署到服务器后静态资源能被正确访问。
2. 使用公网可访问的图片URL
如果是生产环境,需要将图片URL改为公网可访问的地址:
- 配置
STATIC_URL为你的域名+静态路径,例如https://yourdomain.com/static/ - 模板中直接使用完整公网URL,或确保
request.get_host返回公网域名(而非localhost)
模板示例:
{% load static %} {% block content %} <img src="https://yourdomain.com{% static 'img/logo.svg' %}" alt="" /> {% endblock %}
3. 可选:将图片内嵌到邮件中(不依赖外部资源)
如果不想依赖外部服务器的静态资源,可以把图片直接内嵌到邮件里:
- 修改发送邮件的代码:
from django.core.mail import EmailMultiAlternatives from django.conf import settings import os subject = 'Material Requests System' html_message = render_to_string('app/mailing/email.html') plain_message = strip_tags(html_message) from_email = 'blablabla0' to = 'blablabla1' # 创建邮件对象 msg = EmailMultiAlternatives(subject, plain_message, from_email, [to]) msg.attach_alternative(html_message, "text/html") # 读取图片并作为内嵌附件添加 img_path = os.path.join(settings.STATIC_ROOT, 'img/logo.svg') with open(img_path, 'rb') as img_file: msg.attach('logo.svg', img_file.read(), 'image/svg+xml') msg.send()
- 对应的模板修改为引用cid(内容ID):
{% block content %} <img src="cid:logo.svg" alt="" /> {% endblock %}
内容的提问来源于stack exchange,提问作者Andrii Shyrokov
相关产品推荐
相关产品推荐

