You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo 15 Qweb邮件模板t-foreach数据传递失败问题排查

解决邮件模板无法获取timesheet_details数据的问题

问题根源

  1. 直接通过email_body传递timesheet_details时,Odoo会尝试将其作为mail.mail模型的字段处理,但该模型本身没有这个字段,因此抛出错误。
  2. 使用with_context传递后无报错但表格为空,说明上下文变量没有正确注入到模板的渲染环境中。

具体解决方案

方法1:手动渲染模板并注入变量

在发送邮件前,先调用模板的渲染方法,把timesheet_details作为上下文变量传入,直接生成渲染好的邮件正文:

# 假设已获取到目标邮件模板对象template,以及组装完成的timesheet_details
template = self.env['mail.template'].browse(你的模板ID)
# 渲染邮件正文,注入timesheet_details变量
rendered_body = template._render_template(
    template.body_html, 
    '你的业务模型名', 
    self.id, 
    post_process=False, 
    context={'timesheet_details': timesheet_details}
)
# 构建邮件参数并发送
mail_values = {
    'subject': template.subject,
    'body_html': rendered_body,
    'recipient_ids': [(6, 0, 收件人ID列表)],
    'email_from': self.env.user.email_formatted
}
self.env['mail.mail'].create(mail_values).send()

方法2:修正上下文传递逻辑

如果坚持用with_context,要确保变量被传递到模板渲染的上下文环境中:

# 将timesheet_details加入当前环境上下文
self = self.with_context(timesheet_details=timesheet_details)
# 调用模板的发送方法
template.send_mail(self.id, force_send=True)

同时检查模板中的循环语法是否正确,比如:

<t t-foreach="timesheet_details" t-as="detail">
    <tr>
        <td><t t-esc="detail.get('project_name')"/></td>
        <td><t t-esc="detail.get('worked_hours')"/></td>
        <!-- 根据你的数据结构添加其他字段 -->
    </tr>
</t>

方法3:临时扩展mail.mail模型(不推荐)

如果需要直接通过email_body传递,可以临时给mail.mail加字段,但这种方式会污染核心模型,仅作应急用:

# 在你的模块中继承mail.mail并添加字段
class MailMail(models.Model):
    _inherit = 'mail.mail'
    
    timesheet_details = fields.Text(string='工时单详情')

创建邮件时传入该字段,模板中通过object.timesheet_details访问,但需要先把字典列表转为可渲染的格式(比如提前生成HTML片段),复杂度较高,优先推荐前两种方法。

验证要点

  • 确认模板变量名和传递的变量名完全一致(注意大小写)。
  • 渲染前打印timesheet_details,确保是可迭代的字典列表,数据结构正确。
  • 检查模板中t-foreach的语法,比如是否遗漏t-as,循环体是否正确嵌套在表格标签内。

内容的提问来源于stack exchange,提问作者Slavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:19:58