Odoo 15 Qweb邮件模板t-foreach数据传递失败问题排查
解决邮件模板无法获取timesheet_details数据的问题
问题根源
- 直接通过
email_body传递timesheet_details时,Odoo会尝试将其作为mail.mail模型的字段处理,但该模型本身没有这个字段,因此抛出错误。 - 使用
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
相关产品推荐
相关产品推荐

