协同办公

Odoo To-Do 为什么不是一个新模型:project.task 外壳化、待办视图和入职自动任务讲透

很多人以为 Odoo To-Do 应该有个独立模型,但官方源码走的是另一条路:继续复用 project.task,只是在视图、入口和活动分组层面把“私人待办”做成另一种壳。这个设计非常值得协同类产品学习。

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

先说结论

很多系统做“待办”功能时,第一反应都是新建一个模型:

  • 任务是一个模型
  • 私人待办再单独一个模型

但 Odoo 官方没有这么走。

addons/project_todo/models/project_task.pyres_users.py 看,To-Do 依然建立在 project.task 之上,只是通过:

  • 特定视图
  • systray 活动分组
  • 名称生成逻辑
  • onboarding 自动任务

把“私人待办”包装成一种不同体验。

一句话说:

Odoo To-Do 不是新数据模型,而是 project.task 的一层产品壳。

这个思路对协同办公产品非常有启发。


为什么官方没有再造一个 todo.task

从建模角度看,To-Do 和 Task 当然可以拆。

但 Odoo 选择复用 project.task,本质上是在保留几件非常值钱的能力:

  • 现成的活动、消息、负责人、截止日期能力
  • 和项目任务之间的自然转换关系
  • 不必复制一套权限、搜索、看板、日历、活动逻辑

也就是说,官方判断是:

  • 待办和任务在行为上高度相近
  • 真正不同的,主要是产品入口和使用场景

所以更划算的方式不是“再造一套对象”,而是“同一个对象,多一种壳层”。


create() 为什么会自动生成待办标题

project_todo/models/project_task.py 里最先值得看的就是 create()

它的逻辑很朴素,但非常有产品感:

  • 如果没有 name
  • 又没有 project_id
  • 也没有 parent_id
  • 那它倾向把这条记录视为更像 To-Do

这时:

  • 若有 description,就从描述首行抽标题
  • 若连描述都没有,就给一个 Untitled to-do

这说明官方对 To-Do 的用户预期非常清楚:

待办往往比正式项目任务更轻、更随手、更接近“先记下来”。

所以标题可以从正文里懒生成,而不强制用户一开始就严肃命名。

这是典型的协同办公产品手感设计。


为什么官方专门做了一组 To-Do 视图

同一个模型,不代表必须同一种界面。

get_todo_views_id() 返回了一整组 To-Do 专用视图:

  • kanban
  • list
  • form
  • calendar
  • activity

这说明 Odoo 的思路是:

  • 数据层复用 project.task
  • 体验层单独给 To-Do 一套主视图编排

这很重要。

因为 To-Do 的典型用户心智和项目任务不完全一样:

To-Do 更强调

  • 快速捕捉
  • 今天要做什么
  • 个人节奏
  • 轻量整理

Project Task 更强调

  • 项目上下文
  • 多人协作
  • 阶段流转
  • 依赖与交付

所以 Odoo 并没有把它们数据上拆开,而是把体验上拆开。


Systray 为什么要把 Task 和 To-Do 分开统计

project_todo/models/res_users.py_get_activity_groups() 很值得看。

它做了一件很有代表性的事:

  • 先把原来统一的 project.task 活动组拿掉
  • 再按 BOOL(t.project_id) AS is_task 重新拆成两类
  • 有项目的叫 Task
  • 没项目的叫 To-Do

这说明在官方产品心智里:

To-Do 和 Task 可以共用一张表,但在提醒入口上必须被视为两种不同工作负载。

这点特别真实。

因为对一个用户来说:

  • 今天我要回复的私人待办
  • 和项目里需要协同推进的任务

虽然都叫 task,但心理负担完全不同。

如果全部混在同一个提醒桶里,反而不好用。


为什么 project_id 成了两种语义的分水岭

从这套实现可以看出,Odoo 实际上把:

  • 有项目上下文project.task 看作正式任务
  • 无项目上下文project.task 看作更偏个人待办

这不是绝对真理,但它是一个非常聪明的产品切线。

因为它避免了:

  • 额外建模
  • 额外迁移
  • 额外同步

又能让产品自然形成两种心智空间。

对很多企业内部协同系统来说,这是很值得借鉴的:

先问“是不是只差一个上下文”,再决定要不要新建模型。


为什么 To-Do 能一键转成正式 Task

action_convert_to_task() 做的事情看似简单:

  • 把记录打回 project.task 表单打开
  • 同时同步公司上下文

但这件事的产品意义很大。

因为它说明 Odoo 不是把 To-Do 和 Task 切成两座孤岛,而是明确承认:

  • 很多正式任务,最初就是一条私人待办
  • 很多“先记一下”的事,后来会升级成项目事项

所以最好的模型不是两套对象来回复制,而是:

  • 让轻任务自然长成重任务

这正是协同办公里非常常见的工作演化路径。


为什么新用户入职时会自动生成 To-Do

_generate_onboarding_todo() 更能体现官方对 To-Do 的定位。

它会在用户 onboarding 时:

  • 渲染一段欢迎模板
  • 生成标题 Welcome %s!
  • 直接创建一条 project.task
  • 且用 mail_auto_subscribe_no_notify 降低干扰

这说明官方把 To-Do 看成:

  • 最适合承载“个人启动清单”的容器
  • 比正式项目任务更适合做新手引导

换句话说,To-Do 在 Odoo 里不仅是“轻任务”,还是个人工作入口


这套设计对协同产品有什么启发

1. 不要看到新场景就先建新模型

如果核心行为高度相似,先考虑“壳层分化”而不是“数据分叉”。

2. 用视图和入口隔离心智,而不一定用表隔离

用户感受到的是产品形态,不是数据库表。

3. 让轻量事项能平滑升级成正式协同对象

这比在两套系统之间搬运数据顺手得多。

4. 提醒分组要贴近工作语义

同一张表里的记录,也可能需要在入口上分桶。


做相关定制时最容易踩的坑

1. 急着新建待办模型

后面会发现消息、活动、权限、搜索、统计都要重复造。

2. 只复用表,不重做入口体验

那用户就感受不到 To-Do 和 Task 的区别。

3. 不给“轻任务升级”为正式任务的路径

结果个人事项和团队事项割裂。

4. 把所有提醒混成一个桶

个人待办和项目协作会相互淹没。


一句话记忆法

Odoo To-Do 的高明之处,不是新造了一个待办模型,而是把 project.task 通过视图、入口和分组包装成更轻的个人工作壳。

理解这一句,就能明白为什么这套实现既省模型成本,又保留了很强的协同延展性。

DISCUSSION

评论区

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