协同办公

Odoo 主附件为什么不是你最后上传的那个:`message_main_attachment_id` 的选取优先级与过滤边界讲透

很多人以为记录上的主附件就是最近那次上传的文件。源码里 `mail.thread.main.attachment` 明确做了筛选与优先级:先过滤 XML 和 octet-stream,再优先 PDF,其次图片,最后才是其他类型。也就是说,主附件表达的是‘最适合展示/代表该记录的文件’,而不是上传顺序。

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

先说结论

记录上的主附件,不是“最后上传哪个就显示哪个”。

Odoo 会把主附件当成这条记录最值得被代表和展示的文件,因此它会过滤一部分类型,并按 PDF → 图片 → 其他的优先级挑选。

如果你拿“上传顺序”去理解,就会经常误判系统行为。


一、主附件是在哪一步被设置的

mail.thread.main.attachment_message_post_after_hook() 里接管了这个逻辑。

也就是说,很多情况下主附件并不是后台手工单独维护,而是在消息发布后,根据这次消息携带的附件自动决定。

这层设计很重要,因为它把“附件归档”和“协作消息”连在了一起:

  • 你发了一条带附件的消息
  • 记录不仅多了消息历史
  • 还可能顺手更新主附件

二、为什么要过滤 XML 和 octet-stream

源码里有个很实用的细节:默认会过滤掉 XML 和 application/octet-stream

原因很朴素:

  • XML 常常是交换文件、系统数据、电子单据载体
  • octet-stream 往往只是浏览器或上传端没识别出具体类型

这些文件未必适合当成“记录封面”或“主预览对象”。

所以 Odoo 的态度是:

能作为业务交换文件存在,不等于适合作为主附件展示。


三、为什么 PDF 优先于图片

源码里 max() 的排序优先级很明确:

  • PDF 优先
  • 然后图片
  • 再然后其他类型

这不是技术癖好,而是非常接近办公现实。

在很多业务记录里,最能代表当前阶段的文件往往是:

  • 报价单 PDF
  • 合同 PDF
  • 报告 PDF

图片虽然也常用,但通常更像补充说明,而不是正式结果物。


四、为什么它不一定会覆盖已有主附件

_message_set_main_attachment_id() 默认不是无脑覆盖。

只有在:

  • 当前没有主附件,或者
  • 明确 force=True

时才会替换。

这说明 Odoo 不是想让主附件随着每次沟通不停抖动,而是尽量保持一个相对稳定的代表文件。


五、这套机制适合什么,不适合什么

适合:

  • 报价、合同、审批单、说明书等正式文件驱动的协作对象
  • 需要在界面上快速看到“当前代表文件”的场景

不适合:

  • 你想把主附件严格定义为“最后上传文件”
  • 你上传的大量文件类型都不是 PDF/图片,却希望系统自动懂你的业务偏好

这类场景通常需要自定义。


六、最常见误区

误区 1:主附件就是最新附件

不是。它更像“最佳代表文件”。

误区 2:只要上传了文件,主附件一定会变

不是。已有主附件默认不会轻易被覆盖。

误区 3:所有可下载附件都适合当主附件

不是。源码已经明确过滤了部分类型。


七、排错顺序

当用户问“为什么这个文件没当上主附件”时,建议这样查:

  1. 这次文件是不是通过消息附件进入的
  2. 文件 MIME type 是什么
  3. 当前记录是否已经有主附件
  4. 这次调用有没有 force=True
  5. 若有多个附件,谁在 PDF/图片优先级里更靠前

最后一句

主附件表达的是‘这条记录最应该被先看到的文件’,而不是‘最近发生过一次上传’。

只要用这个视角看,它的优先级设计就很合理。

DISCUSSION

评论区

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