跳转至

低代码定制(Studio 风格)

Odoo Studio 是 Enterprise 专属的可视化编辑器。它所做的定制(字段、视图、自动化动作)都是保存在数据库中的普通 Odoo 记录。本插件通过 RPC 创建这些相同的记录,因此你在 Community 版上也能获得 Studio 常见的成果,而无需许可证。

诚实的适用范围

这覆盖的是小型、低代码的改动:一个字段、一处视图调整、一个简单的自动化。它不能替代严肃的模块开发(打包的代码、迁移、测试、复杂的业务逻辑)。若需要这些,请构建一个模块。参见 它像 Odoo Studio 吗?。

v1.5.0 新增:这些配方需要配置档 builder

默认权限配置档(standard)把字段、视图和自动化视为定制:odoo_add_field 和 odoo_add_automation 不会被列出,对 ir.ui.view 的 odoo_create 会被拒绝。这些配方需要 Permission profile builder(或 full),你可以在 /plugin → odoo-tools → Configure options 中设置它,然后重新连接服务器(/mcp)。请只在沙箱和预发布环境中使用 builder:自动化会在 Odoo 服务器上运行 Python,因此在机密性方面 builder 等同于 full。Claude 从不自行更改该选项或策略文件;如果策略拒绝了某一步,它会告诉你需要哪个配置档并停下来。参见 权限策略。

在 builder 下仍有两项限制:名称看起来像凭据的字段(x_api_token)会在读取时被屏蔽;写入 website.page 遵循指向其视图(ir.ui.view)的委托规则:参见 委托。

改动存放在哪里

存放在实例/数据库中,与 Studio 完全一样,而不是像仓库中的模块代码那样。它们像手动定制一样在升级中保留下来。如果你需要仓库中的代码,那属于模块开发,不在本插件的范围之内。

1. 添加自定义字段

使用 odoo_add_field 工具。它会创建一个 state='manual' 的字段,并强制加上必需的名称前缀 x_。

odoo_add_field {
  "model": "res.partner",
  "name": "loyalty_points",
  "label": "Loyalty points",
  "field_type": "integer"
}

名称 loyalty_points 会变成 x_loyalty_points。

关系型示例:

odoo_add_field { "model": "res.partner", "name": "account_manager",
  "label": "Account manager", "field_type": "many2one", "relation": "res.users" }

对于 selection 字段,将 selection 传为 [["a","A"],["b","B"]]。创建字段之后,把它添加到一个表单视图或列表视图中(步骤 2),用户才能看到它。

2. 调整视图(继承)

没有专门的工具;请对 ir.ui.view 使用 odoo_create,配合一个继承的 arch,这样就不会覆盖基础视图。先找到要扩展的视图:

odoo_search_read { "model": "ir.ui.view",
  "domain": [["model","=","res.partner"],["type","=","form"]],
  "fields": ["name","xml_id"], "limit": 5 }

然后创建一个继承视图:

odoo_create { "model": "ir.ui.view", "values": {
  "name": "res.partner.form.x_loyalty",
  "model": "res.partner",
  "inherit_id": <base_view_id>,
  "arch_db": "<xpath expr=\"//field[@name='email']\" position=\"after\"><field name=\"x_loyalty_points\"/></xpath>"
}}

优先使用 xpath ... position="after|before|inside|replace",而不是重写整个视图。

3. 添加自动化

使用 odoo_add_automation。其 Python 代码在 Odoo 的 safe_eval 下运行;工具会在发送之前对它进行校验,这一点在 Odoo online/SaaS 中尤为重要,因为在那里,任意 Python 代码会在服务器端被拒绝。

odoo_add_automation {
  "model": "crm.lead",
  "name": "Flag hot leads",
  "trigger": "on_create_or_write",
  "code": "for rec in records:\n    if rec.probability and rec.probability > 80:\n        rec.write({'priority': '3'})"
}

safe_eval 规则(由工具强制执行)

代码在 Odoo 的 safe_eval 下运行。禁止:import、def、class、return、with、访问以下划线或双下划线(__)开头的名称或属性,以及属性赋值(rec.field = value 会编译为 STORE_ATTR 并被拒绝,请用 rec.write({...}))。工具会在发送之前拒绝这些结构,并给出清晰的修正建议,因此你会在本地就发现问题,而不是通过服务器错误才知道。

该上下文中可用的名称:env、model、record/records、datetime、dateutil、time、UserError(Odoo 10-12 上为 Warning)。要返回一个动作,请把 action = {...} 作为 最后一条语句进行赋值(绝不要用 return)。

这些配方需要管理员权限

创建 ir.model.fields、ir.ui.view、base.automation(Odoo 10 上为 base.action.rule)及其 ir.actions.server 需要技术权限(设置 / 技术)。若使用 安全 中推荐的最小权限业务用户,每个配方都会报 AccessError:请以管理员身份运行这些配方。除了 Odoo 权限之外,插件的权限策略还必须设为 builder 或 full。

Enterprise 对比 Community

  • 这里创建的字段、视图和自动化在两个版本中都能工作。
  • 在 Enterprise 中,它们不会出现在 Studio 编辑器里(它们没有被标记为 web_studio 定制),但在运行时表现相同。
  • Enterprise 专属的模型(例如 documents.document)在 Community 中仍然无法使用:兼容层会抛出一个清晰的错误。

验证(完成的定义)

读回记录并确认效果:

  • 字段:odoo_fields_get { "model": "<model>" } 会显示新的 x_ 字段。
  • 视图:在 Odoo 中打开表单(或读取继承的 ir.ui.view)。
  • 自动化:在一条记录上触发它,并读取被修改的字段。

技能参考:/odoo-tools:odoo-studio-style。