Django用html_message发HTML模板邮件,未渲染{{ message }}变量
问题根因排查与修复方案
核心疏漏点
你的渲染失效问题完全是代码执行顺序和参数遗漏导致的,没有复杂的底层问题:
- 调用
render_to_string生成邮件HTML内容时,完全没有传入模板渲染需要的上下文参数,拿到的渲染结果是带着原生{{ message }}占位符的无效HTML。邮件客户端识别到这种未解析的模板内容时,会自动降级为只展示send_mail传入的纯文本内容,根本不会渲染带占位符的无效HTML,这就是你收到的邮件只有纯文本、看不到加粗USER的直接原因。 - 代码执行顺序逻辑错误:你把上下文字典的定义放在了
render_to_string、send_mail两个函数调用之后,Python是顺序执行代码的,前面调用函数的时候,根本拿不到后面才定义的变量。
可直接复用的修复后代码
调整执行顺序,把上下文组装提前,调用模板渲染函数时显式传入上下文,就能一次性解决所有问题:
from django.template.loader import render_to_string from django.core.mail import send_mail def home(request): # 先定义所有需要传到模板里的自定义变量 message_name = "NAME" message_email = "EMAIL" message = "USER" # 组装统一的上下文字典,前端页面、邮件模板可以直接复用同一份数据 email_context = { 'message': message, 'message_name': message_name, 'message_email': message_email } # 渲染邮件HTML时,必须把上下文作为第二个参数传入——这就是你之前漏的最关键的一步 msg_html = render_to_string('email/email.html', email_context) # 发送邮件,这里的纯文本内容是给不支持HTML渲染的老旧邮件客户端做兜底用的 send_mail( subject=f'message from {message_name}', message_body=f"Hello {message} - your account is activated.", from_email=message_email, recipient_list=['myemail@outlook.de'], html_message=msg_html, fail_silently=False, ) # 给前端返回页面时,直接复用同一份上下文渲染即可 return render(request, 'email/email.html', email_context)
容易踩的额外坑
- 后续要在邮件模板里加新的自定义数据(比如用户名、激活链接),只要把对应的键值对加到
email_context字典里,模板里用相同的变量名取值就行,和普通Django前端模板的渲染逻辑完全一致。 - 别省略
send_mail的纯文本参数,很多企业邮箱、老旧邮件客户端不支持HTML渲染,兜底的纯文本内容是必须的。 - 第一次发邮件前可以把渲染好的
msg_html打印到控制台,确认{{ message }}已经被替换成实际的"USER"值再发送,避免出现占位符残留的低级问题。
内容的提问来源于stack exchange,提问作者JEA
相关产品推荐
相关产品推荐

