协同办公

Odoo 邮件模板为什么常常“看着能写、保存就报错”:渲染校验、默认收件人和附件归属讲透

很多人把 Odoo 邮件模板当成一个富文本编辑器,但 mail.template 源码真正关心的是:模板能不能渲染、默认收件人是否成立、附件归属是否安全。理解这三层,才能把协同邮件做稳。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的邮件模板不是“写完 HTML 就能发”。

mail.template 模型可以看到,系统在保存和发送前最在意三件事:

  • 模板字段能不能在目标模型上成功渲染
  • 收件人到底来自默认对象,还是来自模板里显式写的表达式
  • 模板挂的附件是否正确转移到消息上下文里

所以模板问题大多数不是“编辑器抽风”,而是:

渲染上下文、收件人来源和附件归属三者没有对齐。


为什么模板保存时就会做渲染校验

mail.template.create()write() 之后,都会走 _check_can_be_rendered()

这意味着 Odoo 的思路很明确:

  • 与其让错误拖到真正发信时爆炸
  • 不如在保存模板时,就先拿一个实际记录试渲染

因此常见报错并不是“系统挑剔”,而是模板里某个动态表达式在当前模型上根本跑不通。

比如:

  • 目标模型没有这个字段
  • 语法能过,但值链路会遇到空对象
  • 某段表达式在 sample record 上直接抛异常

这也是为什么很多人明明看着模板写得很像对,保存却失败。


use_default_to 为什么经常被误解

use_default_to 的帮助文案说得很直接:默认收件人来自记录本身。

换句话说,模板默认优先尊重业务对象已有的“应该通知谁”。

只有当你显式填写:

  • email_to
  • partner_to
  • email_cc

时,系统才会引入额外的模板级收件人逻辑。

这对协同邮件特别重要。

因为很多业务对象本来就已经有一套默认联系人关系,比如:

  • 客户
  • 跟进人
  • 参与人
  • attendee / partner 关联

如果你不理解 use_default_to,最常见的后果就是:

  • 以为模板没收件人,其实对象早就有默认收件人
  • 或者反过来,手写了 email_to,却把对象原本的通知关系绕开了

为什么 reply_to 不是随便填个邮箱

源码里对 reply_to 的描述很克制:它主要用于 mass 模式下,且回复不会回到原 discussion thread 时。

这句话背后的意思是:

  • 正常线程化协作,最好让回复回到原线程
  • reply_to 主要是在“无法自然续帖”的群发场景下做引流

很多团队一上来就把 reply_to 当万能回邮口,其实容易制造新的混乱:

  • 本该回原业务对象的邮件,被改投到另一个地址
  • Chatter 连续性被打断
  • 邮件看起来发出去了,但回复再也回不到正确上下文

所以 reply_to 更像边界修正工具,不是默认必填项。


附件为什么要做 ownership 修复

_fix_attachment_ownership() 会把模板附件写回到模板自身的 res_model / res_id

这一步很像后台 housekeeping,但其实非常关键。

原因是模板附件不是普通文件列表,它还涉及:

  • 访问权限
  • 后续消息引用
  • 发送时是否能被正确复制到 mail compose / mail message

如果附件归属乱了,常见表现是:

  • 内部用户看得到,外部流程拿不到
  • 发信时附件偶尔丢失
  • 附件看似在模板上,实际上关联到了错误对象

这类 bug 很隐蔽,而 Odoo 选择在模板写入后主动修正归属,就是为了减小这种隐患。


为什么模板分类会影响协作治理

template_category 会把模板区分成:

  • base template
  • hidden template
  • custom template

这不是 UI 装饰,而是在告诉你:

  • 哪些是系统级基准模板
  • 哪些是 XML 自带但已隐藏或不建议直接用
  • 哪些是业务自己新增的模板

对协同办公团队来说,这个分类非常有用。

因为真正麻烦的不是“模板太少”,而是:

  • 同一业务流程被人复制出很多近似版本
  • 没人知道哪一份才是主模板
  • 某个自定义模板长久没有校验,却一直挂在自动动作里

最容易踩的误区

误区一:模板能预览,就一定能保存

不一定。预览往往只是局部成功,保存时的 _check_can_be_rendered() 更严格。

误区二:把收件人全部硬编码进模板

这样会绕过很多模型自己的默认收件逻辑,长期维护很痛苦。

误区三:把模板附件当普通素材库

模板附件是“可发送对象”的组成部分,不只是素材托管。


模板报错时的排查顺序

建议按下面顺序查:

  1. 目标 model_id 是否选对
  2. 有问题的字段是不是动态字段:subject、body_html、email_to、reply_to 等
  3. 拿一个真实记录,验证表达式是否能渲染到具体值
  4. 检查 use_default_to 与显式 email_to 是否互相打架
  5. 附件是否是模板自己的附件,而不是历史消息残留附件

一句话记忆

Odoo 邮件模板的稳定性,不取决于编辑器写得多漂亮,而取决于渲染上下文、默认收件人和附件归属是否一致。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。