Django Rest Framework使用django-templated-mail发邮件时图片无法加载问题
问题根源
- 你传递给邮件模板的
image是DjangoImageField实例,直接渲染只会输出相对路径/实例对象标识,邮件客户端无法识别本地相对路径 - 就算你拼接了站点域名的完整外链,大部分邮件客户端也会默认拦截第三方外链图片,导致加载失败
- 额外问题:你把img标签写在了模板的
blocktrans翻译块内,变量会被转义无法正常解析
方案1:使用外链图片(仅适合不介意客户端拦截的场景)
- 首先在Django
settings.py中配置完整的MEDIA_URL,必须带上你的站点域名,示例:
# settings.py MEDIA_URL = "https://你的正式站点域名/media/"
- 修改usecase.py中传递context的逻辑,获取图片的完整访问URL:
# usecase.py SendEmail( context={ "fullname": self.data['full_name'], # 调用已保存实例的ImageField url属性获取完整路径 'image': self._mail.image.url } ).send(to=[self.data['email']])
- 修正邮件模板的变量解析问题:
<!-- email.html 修正后的html_body部分 --> {% block html_body %} <p>hello {{ fullname }}</p> <!-- 不要把变量放到blocktrans标签内,会无法解析 --> <img src="{{ image }}" alt="email-image"> <p>Thanks for using our site!</p> {% endblock html_body %}
方案2:内嵌图片到邮件(推荐,兼容性最好)
这种方案是把图片作为邮件的内嵌附件发送,不需要依赖外链,不会被邮件客户端拦截
- 修改
SendEmail类,添加图片内嵌逻辑:
from templated_mail.mail import BaseEmailMessage class SendEmail(BaseEmailMessage): template_name = 'email.html' def get_context_data(self): context = super().get_context_data() # 拿到传递进来的ImageField实例 image = context.pop('image') # 把图片添加为内嵌附件,生成唯一cid标识 img_cid = self.attach_file(image.path, subtype='image/png') # 把cid传给模板 context['image_cid'] = img_cid return context
- 修改邮件模板的img标签,用cid引用内嵌图片:
<!-- email.html --> <img src="cid:{{ image_cid }}" alt="email-image">
- usecase.py传递context的逻辑无需修改,保持传递image实例即可。
内容的提问来源于stack exchange,提问作者lord stock
相关产品推荐
相关产品推荐

