在 Odoo 里,只读字段看似简单,却在数据保护与流程治理中扮演关键角色——远不止界面上变灰那么简单。
无论你是看到表单中某些项不能编辑的业务用户,还是负责定制 Odoo 的开发者,这篇指南会把只读字段从概念、实现到实务落地讲清楚。
理解只读字段的机制,是保证工作流可靠、避免数据被误改并为团队提供稳定体验的必要前提。
本教程同时覆盖业务层面和技术实现——无论是在界面上配置规则,还是在模块中写代码,你都能找到实操要点。
什么是 Odoo 中的只读字段
在 Odoo 中,只读字段是指可以查看但不能在界面上直接编辑的字段:值对用户可见,但输入被禁止。
在表单视图中,只读字段通常以非交互的文本展示,而非可输入的表单控件;不同主题下它们可能表现为灰显或扁平化的样式。
在 Odoo 的架构里,只读行为可以在两个层面上实现:
- 模型层(Python/ORM):在数据模型中设定后,字段在所有视图和上下文中都不可编辑。
- 视图层(XML):在某个具体视图或特定条件下使字段只读。
二者的差别很重要:模型层的只读是全局约束,无法通过界面绕过;视图层只读只限制特定界面的交互,但后台代码或其他视图仍可能写入该字段。
只读并不是一种独立的数据类型,而是一种属性,可应用于 Odoo 支持的任意字段类型,例如 Char、Integer、Float、Many2one、Date 等,用来控制运行时的编辑权限。
只读字段的工作原理
要掌握只读字段的行为,需要同时理解 ORM(Python)端的定义和视图(XML)端的展示限制。
模型层(ORM)中的只读
在 ORM 里,可以在字段定义时直接写入 readonly=True,这通常用于计算字段或由系统生成的值,确保用户无法通过界面修改这些来源于其他数据的字段。
这类写法属于 Odoo Python fields 的标准用法,文档中有详细说明,它对所有视图生效,与使用哪个界面无关。
基于状态的只读控制
常见模式是根据单据状态改变字段的可编辑性——例如单据从草稿流转到已确认后,关键字段被锁定以防止后续篡改,这是销售、采购、会计模块中常见的做法。
在较早版本的 Odoo(如 16 及更早)通常使用 view XML 的 attrs 属性配合条件表达式实现;从 Odoo 17 开始,可以用更紧凑的内联条件语法直接写在字段定义上。
无论写法如何,目的相同:在草稿阶段允许编辑,流程推进后自动变为只读——这是字段配置中最基本也最常见的逻辑。
计算字段与只读的关系
默认情况下,计算字段是只读的:因为它们的值由 compute 方法计算得出,不应被直接改写。
如果需要把计算结果存入数据库以便检索或排序,可以设置 store=True,这样字段会被持久化,利于性能和搜索过滤。
让计算字段可写
当确实需要让计算字段接受手工输入时,可以为其定义 inverse 方法,说明用户写入该字段时如何将值反写到源字段或其他数据。没有 inverse 的计算字段仍然保持只读。
业务场景举例
只读字段在各个模块中随处可见,下面列出五个常见的业务实例来帮助理解。
1. CRM:锁定已成单或已丢失的商机信息
在 CRM 中,预期收入和预计成交日期在商机处理阶段可修改;一旦标记为“赢单”或“丢单”,这些字段应当被锁定以保存当时的真实记录。
这样可以避免事后篡改导致销售报表与管道分析失真。
2. 销售:保护已确认订单行
当销售订单从草稿变为已确认后,订单行(如产品、数量、价格)一般设为只读,防止在客户已收到确认后被随意更改。
如需更改,通常要求显式重置为草稿以保留审计轨迹,让修改变成可追溯的动作。
3. 库存:已验证出入库的数量
在仓库操作中,一旦交货或收货被验证,实际操作数量就应被锁定,以确保库存价值和账面记录与实际流转一致。
如果验证后仍可随意改动数量,可能会在多个库位间悄然造成库存失衡。
4. 会计:已过账的分录行
会计分录一旦过账,其明细行通常被设为只读,这在很多国家既是合规要求,也是会计核算的基本原则。
允许在过账后任意修改会破坏财务报表的可靠性并带来合规风险。
5. 生产:完成的工单记录
在生产模块中,一旦工单标记为完成,实际工时与产出数量通常被锁定,以便为成本核算与绩效分析提供可靠数据。
如何创建或自定义只读字段
配置只读字段主要有两条路径:使用无代码的 Odoo Studio 快速设置,或通过 Python 与 XML 写入代码获得更细粒度的控制。
通过 Odoo Studio 配置
Odoo Studio 提供可视化的方式来添加或修改字段的只读属性,无需编写代码,适合管理员和业务顾问快速实施规则。
- 在主菜单点击 Odoo Studio(铅笔图标)进入编辑模式。
- 定位到你要修改字段的表单视图。
- 点击需要配置的字段以打开属性面板。
- 在右侧属性面板里切换“只读”选项。
- 保存并退出 Studio。
Studio 还支持用条件表达式设置< strong>条件只读 strong>,比如当某个状态字段等于特定值时才锁定,从而在不写代码的情况下实现复杂业务规则。
对于需要快速落地且兼容升级的需求,Studio 是顾问与管理员的首选;通过 Studio 做的改动会存入数据库,不会在模块升级时被覆盖。
通过 Python 实现技术定制
开发者在自定义模块中通常在 Python 模型里直接为字段设置 readonly 属性,这是标准的 Odoo 开发方式。
可通过 readonly=True 将字段设为永久只读;若需按状态控制,可使用 states 参数来定义何时可写何时只读。
当你在现有模型上新增自定义字段时,把逻辑放在模型层可以让规则更贴近数据源,避免在多个视图中重复维护。
通过视图 XML 设置只读属性
在视图层面,可以在字段元素上直接写 readonly 属性来限制当前视图中的编辑,这也是常见的定制流程。
视图级的只读优点是灵活:同一字段在不同视图中可以呈现不同的可编辑性,而不必修改底层模型定义,适合在不改动核心代码的情况下对标准字段施加限制。
在 Odoo 17 中,用于条件只读的内联表达式比旧版本的 attrs 写法更简洁;但具体采用哪种语法取决于你使用的 Odoo 版本。
最佳实践建议
正确使用只读字段的关键是把控制施加在合适的层级,并基于合理的业务理由来设计。下面列出常用的建议。
1. 若场景依赖上下文,优先在视图层面设置只读
仅当字段在部分视图或某些状态下需要只读时,应在视图层面控制,这样后端流程或 API 依然可以在必要时写入字段,保证灵活性。
2. 让只读规则与单据生命周期保持一致
只读条件应当反映业务流程:当文档进入不应再改动的阶段时锁定字段,给用户一个符合预期的使用体验。
3. 在不同用户角色下进行测试
只读设置可能与访问权限产生交互影响。务必以普通用户和管理员两种身份测试,确保各角色看到的行为符合预期。
4. 在合适的场景下将只读与必填结合使用
例如某些字段在草稿阶段为必填,而在后续阶段则变为只读,可在视图中同时配置 required 与 readonly 来实现这一模式。
5. 为你的只读逻辑留下文档注释
在自定义开发中,务必在代码或视图中说明为什么设置只读,这能帮助后续维护人员理解背后的业务原因而非仅看技术实现。
6. 对于简单需求,优先用 Studio 快速且升级安全的改法
若 Studio 能满足业务逻辑,就避免用 Python 过度定制;只有当需要复杂跨字段判断或与自定义计算字段集成时,才动用代码层面的修改。
常见陷阱与注意事项
即便是经验丰富的用户和开发者,也会在使用只读字段时遇到一些常见问题,了解这些可以避免后续麻烦。
把视图级只读误当作安全边界
视图上的只读只是前端限制,无法阻止通过 XML-RPC、ORM write 或服务器动作绕过。若想彻底禁止写入,必须在 ORM 层或访问控制中强制约束,而不能仅依赖视图设置。
把临时应急的只读设为永久只读
出于安全或便利考虑把字段直接设为模型层只读,可能会阻断合法的纠正流程(例如恢复为草稿后需要修改的场景)。在做出永久性设置前,先理清完整的生命周期需求。
忽视 onchange 方法的影响
如果只读字段在 onchange 方法中被引用,该方法仍可能尝试写入该字段,导致界面出现闪烁、回滚或报错。编写 onchange 时要考虑字段的可写性。
没有在所有视图中一致应用只读
某个字段在表单视图被设为只读,但在列表或看板视图中未加限制就可能仍可编辑。请检查所有出现该字段的视图,确保规则一致。
继承标准模型时产生的副作用
在继承标准模型并对已有字段添加 readonly=True 时,该变更会影响展示该字段的所有视图,包括标准视图。确认此改动不会破坏原有功能或与其他定制冲突。
总结
只读字段是 Odoo 中引导用户按流程操作、保护数据不被误改以及实现业务规则的基础工具。
关键在于判断应在视图层还是模型层施加只读,并确保条件与团队的实际工作方式相符。合理设计的数据模型会在单据生命周期的关键节点使用只读来防止错误发生。
无论是通过 Odoo Studio 的无代码配置,还是在模块中用 Python 与 XML 编写规则,只读字段的核心逻辑是一致的:展示数据,但阻止非预期的修改。
虽然不是 Odoo 定制里最热议的话题,但只读字段的影响力却很大,常常决定系统是否能稳健运行。
在 Dasolo,我们帮助企业在各行业实施、定制并优化 Odoo。如果你需要在字段配置、工作流设计或数据模型优化上获得支持,我们可以提供咨询和实施服务。 联系我们 告诉我们你的项目需求。