odoo-17.0

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Odoo 17.0 Development Skill

Odoo 17.0 开发技能

A comprehensive skill set for building production-quality Odoo 17.0 custom modules. Covers the full development lifecycle: module structure, ORM, views, actions, performance, and testing — following official Odoo coding guidelines.
一套用于构建生产级Odoo 17.0自定义模块的全面技能集合。涵盖完整开发生命周期:模块结构、ORM、视图、动作、性能及测试——遵循Odoo官方编码规范。

When to Apply

适用场景

Reference these rules when:
  • Creating or extending a custom Odoo 17.0 module
  • Defining models, fields, or compute methods
  • Writing
    @api
    decorators, constraints, or onchange handlers
  • Building XML views, menus, and actions
  • Optimizing queries or processing large recordsets
  • Writing unit tests, integration tests, or UI tours
  • Adding chatter, sequences, ratings, or portal access to a model
在以下场景中参考这些规则:
  • 创建或扩展Odoo 17.0自定义模块
  • 定义模型、字段或计算方法
  • 编写
    @api
    装饰器、约束或onchange处理器
  • 构建XML视图、菜单与动作
  • 优化查询或处理大型记录集
  • 编写单元测试、集成测试或UI向导
  • 为模型添加 chatter、序列、评分或门户访问权限

Rule Categories by Priority

按优先级划分的规则类别

PriorityCategoryImpactPrefix
1Module ManifestHIGH
manifest-
2ORM ModelsHIGH
models-
3ORM FieldsHIGH
fields-
4API DecoratorsHIGH
decorators-
5Recordset & DomainsMEDIUM
recordsets-
6ActionsMEDIUM
actions-
7PerformanceMEDIUM
performance-
8TestingMEDIUM
testing-
9MixinsLOW
mixins-
PriorityCategory影响程度Prefix
1Module Manifest
manifest-
2ORM Models
models-
3ORM Fields
fields-
4API Decorators
decorators-
5Recordset & Domains
recordsets-
6Actions
actions-
7Performance
performance-
8Testing
testing-
9Mixins
mixins-

Quick Reference

快速参考

1. Module Manifest (HIGH)

1. Module Manifest(高优先级)

  • manifest-required-keys
    — Every module must have
    name
    ,
    version
    ,
    depends
    ,
    license
    ,
    installable
  • manifest-data-order
    — Security CSV always first in
    data
    , menus always last
  • manifest-assets-bundle
    — Register JS/OWL/SCSS files under
    assets.web.assets_backend
  • manifest-version-format
    — Use
    {odoo}.{major}.{minor}.{patch}
    e.g.
    17.0.1.0.0
  • manifest-dependencies
    — Missing or wrong
    depends
    prevents module installation
  • manifest-required-keys
    — 每个模块必须包含
    name
    version
    depends
    license
    installable
  • manifest-data-order
    — 安全CSV文件始终在
    data
    中排首位,菜单始终排最后
  • manifest-assets-bundle
    — 在
    assets.web.assets_backend
    下注册JS/OWL/SCSS文件
  • manifest-version-format
    — 使用
    {odoo}.{major}.{minor}.{patch}
    格式,例如
    17.0.1.0.0
  • manifest-dependencies
    — 缺失或错误的
    depends
    会导致模块无法安装

2. ORM Models (HIGH)

2. ORM Models(高优先级)

  • models-class-order
    — Follow canonical attribute → field → constraint → compute → CRUD → action → helper order
  • models-type-selection
    — Use
    Model
    for persistence,
    TransientModel
    for wizards,
    AbstractModel
    for mixins
  • models-inherit-modes
    — Know the 4
    _inherit
    modes: extend, copy, compose, delegate
  • models-sql-constraints
    — Prefer
    _sql_constraints
    over Python for uniqueness checks
  • models-required-attributes
    _name
    and
    _description
    are required on every new model
  • models-class-order
    — 遵循规范的属性→字段→约束→计算→CRUD→动作→辅助方法顺序
  • models-type-selection
    — 持久化模型使用
    Model
    ,向导使用
    TransientModel
    ,混合类使用
    AbstractModel
  • models-inherit-modes
    — 了解4种
    _inherit
    模式:扩展、复制、组合、委托
  • models-sql-constraints
    — 优先使用
    _sql_constraints
    而非Python代码进行唯一性校验
  • models-required-attributes
    — 每个新模型都必须包含
    _name
    _description

3. ORM Fields (HIGH)

3. ORM Fields(高优先级)

  • fields-monetary-currency
    Monetary
    fields always require a paired
    currency_field
  • fields-many2one-index
    — Always set
    index=True
    on
    Many2one
    fields used in searches
  • fields-store-decision
    — Use
    store=True
    only when field needs to be searched or sorted
  • fields-m2m-commands
    — Use ORM write commands
    (0,0,v)
    (4,id)
    (6,0,ids)
    for relational writes
  • fields-selection-add
    — When extending a
    Selection
    , always define
    ondelete
    for new keys
  • fields-monetary-currency
    Monetary
    字段必须始终配对
    currency_field
  • fields-many2one-index
    — 用于搜索的
    Many2one
    字段始终设置
    index=True
  • fields-store-decision
    — 仅当字段需要被搜索或排序时才使用
    store=True
  • fields-m2m-commands
    — 使用ORM写入命令
    (0,0,v)
    (4,id)
    (6,0,ids)
    进行关联写入
  • fields-selection-add
    — 扩展
    Selection
    时,必须为新键定义
    ondelete

4. API Decorators (HIGH)

4. API Decorators(高优先级)

  • decorators-depends-completeness
    — List ALL fields that affect the computed result
  • decorators-depends-assign-all-branches
    — Always assign computed field in every code path
  • decorators-constrains-exception
    @api.constrains
    must raise
    ValidationError
    , never
    UserError
  • decorators-constrains-loop
    — Always loop
    for rec in self
    inside
    @api.constrains
  • decorators-onchange-not-enforced
    @api.onchange
    does not run on programmatic create/write
  • decorators-onchange-newid
    self.id
    inside
    @api.onchange
    is a
    NewId
    , not an integer
  • decorators-create-multi
    — Always use
    @api.model_create_multi
    for
    create()
    overrides in 17.0
  • decorators-depends-context-no-store
    — Fields with
    @api.depends_context
    cannot be
    store=True
  • decorators-depends-completeness
    — 列出所有影响计算结果的字段
  • decorators-depends-assign-all-branches
    — 在所有代码分支中都必须为计算字段赋值
  • decorators-constrains-exception
    @api.constrains
    必须抛出
    ValidationError
    ,绝不能抛出
    UserError
  • decorators-constrains-loop
    — 在
    @api.constrains
    内部必须始终遍历
    for rec in self
  • decorators-onchange-not-enforced
    @api.onchange
    不会在程序化创建/写入时运行
  • decorators-onchange-newid
    @api.onchange
    内部的
    self.id
    NewId
    ,而非整数
  • decorators-create-multi
    — 在17.0版本中,重写
    create()
    时必须始终使用
    @api.model_create_multi
  • decorators-depends-context-no-store
    — 使用
    @api.depends_context
    的字段不能设置
    store=True

5. Recordset & Domains (MEDIUM)

5. Recordset & Domains(中优先级)

  • recordsets-search-count
    — Use
    search_count()
    instead of
    len(search())
    for counting
  • recordsets-batch-write
    — Call
    write()
    on the whole recordset, never inside a loop
  • recordsets-batch-create
    — Pass a list to
    create([...])
    instead of calling it in a loop
  • recordsets-domain-operators
    |
    and
    &
    are prefix operators applying to the next two conditions
  • recordsets-sudo-comment
    — Always add a comment explaining why
    sudo()
    is used
  • recordsets-raw-sql-params
    — Never format SQL strings; always use
    %s
    parameterized queries
  • recordsets-search-count
    — 计数时使用
    search_count()
    而非
    len(search())
  • recordsets-batch-write
    — 对整个记录集调用
    write()
    ,绝不在循环内调用
  • recordsets-batch-create
    — 传入列表
    create([...])
    而非在循环内调用
    create()
  • recordsets-domain-operators
    |
    &
    是前缀运算符,作用于后续两个条件
  • recordsets-sudo-comment
    — 使用
    sudo()
    时必须添加注释说明原因
  • recordsets-raw-sql-params
    — 绝不能格式化SQL字符串;始终使用
    %s
    参数化查询

6. Actions (MEDIUM)

6. Actions(中优先级)

  • actions-window-menu
    — Always bind leaf
    <menuitem>
    to an
    ir.actions.act_window
    record
  • actions-data-order
    — Declare actions in view XML, menus in a separate
    menus.xml
    loaded last
  • actions-python-return
    — Return action dicts from Python methods to open views or wizards
  • actions-cron-method
    — Cron methods must be decorated with
    @api.model
    and handle their own errors
  • actions-server-binding
    — Use
    binding_model_id
    to add server actions to the Action dropdown
  • actions-window-menu
    — 始终将叶子节点
    <menuitem>
    绑定到
    ir.actions.act_window
    记录
  • actions-data-order
    — 在视图XML中声明动作,菜单在单独的
    menus.xml
    中声明并最后加载
  • actions-python-return
    — 从Python方法返回动作字典以打开视图或向导
  • actions-cron-method
    — Cron方法必须使用
    @api.model
    装饰,并自行处理错误
  • actions-server-binding
    — 使用
    binding_model_id
    将服务器动作添加到动作下拉菜单

7. Performance (MEDIUM)

7. Performance(中优先级)

  • performance-prefetch
    — Rely on ORM prefetch; use
    mapped()
    to extract cross-record field values
  • performance-no-loop-write
    — Never call
    write()
    or
    create()
    inside a
    for
    loop
  • performance-index-searched-fields
    — Add
    index=True
    on fields used in
    search()
    domains or
    ORDER BY
  • performance-read-group
    — Use
    read_group()
    for aggregations instead of loading full recordsets
  • performance-invalidate-after-sql
    — Call
    invalidate_model()
    after any raw SQL write
  • performance-prefetch
    — 依赖ORM预取;使用
    mapped()
    提取跨记录字段值
  • performance-no-loop-write
    — 绝不在
    for
    循环内调用
    write()
    create()
  • performance-index-searched-fields
    — 在用于
    search()
    域或
    ORDER BY
    的字段上添加
    index=True
  • performance-read-group
    — 聚合操作使用
    read_group()
    而非加载完整记录集
  • performance-invalidate-after-sql
    — 执行任何原生SQL写入后调用
    invalidate_model()

8. Testing (MEDIUM)

8. Testing(中优先级)

  • testing-setup-class
    — Use
    setUpClass
    for shared fixtures;
    setUp
    only when full isolation is needed
  • testing-post-install-tag
    — Tag tests with
    @tagged('post_install', '-at_install')
  • testing-constrains-coverage
    — Every
    @api.constrains
    method must have a test that triggers it
  • testing-wizard-pattern
    — Test wizards by creating them with context, then calling the action method
  • testing-tour-js
    — UI tours must be registered in the
    web_tour.tours
    registry and tested via
    HttpCase
  • testing-setup-class
    — 共享测试夹具使用
    setUpClass
    ;仅在需要完全隔离时使用
    setUp
  • testing-post-install-tag
    — 测试用
    @tagged('post_install', '-at_install')
    标记
  • testing-constrains-coverage
    — 每个
    @api.constrains
    方法都必须有触发它的测试用例
  • testing-wizard-pattern
    — 通过传入上下文创建向导,再调用动作方法进行测试
  • testing-tour-js
    — UI向导必须注册到
    web_tour.tours
    注册表,并通过
    HttpCase
    测试

9. Mixins (LOW)

9. Mixins(低优先级)

  • mixins-mail-thread
    — Add
    _inherit = ['mail.thread', 'mail.activity.mixin']
    for chatter + activities
  • mixins-tracking
    — Use
    tracking=True
    on fields to log changes in the chatter automatically
  • mixins-sequence
    — Use
    ir.sequence
    +
    next_by_code()
    in field
    default=
    for auto-numbering
  • mixins-portal
    — Implement
    _compute_access_url
    when using
    portal.mixin
  • mixins-message-post
    — Use
    message_post()
    for programmatic chatter messages
  • mixins-mail-thread
    — 添加
    _inherit = ['mail.thread', 'mail.activity.mixin']
    以实现chatter + 活动功能
  • mixins-tracking
    — 在字段上设置
    tracking=True
    以自动在chatter中记录变更
  • mixins-sequence
    — 使用
    ir.sequence
    +
    next_by_code()
    作为字段
    default=
    实现自动编号
  • mixins-portal
    — 使用
    portal.mixin
    时需实现
    _compute_access_url
  • mixins-message-post
    — 程序化发送chatter消息使用
    message_post()

How to Use

使用方法

Read individual skill files for detailed explanations, correct and incorrect code examples, and gotchas:
odoo-manifest.md
odoo-orm-models.md
odoo-orm-fields.md
odoo-orm-decorators.md
odoo-orm-recordsets.md
odoo-actions.md
odoo-performance.md
odoo-testing.md
odoo-mixins.md
Each file contains:
  • Why it matters in Odoo 17.0
  • Incorrect code examples with explanation (
    # ❌ WRONG
    )
  • Correct code examples with explanation (
    # ✅ CORRECT
    )
  • Decision trees and edge cases
阅读单个技能文件以获取详细说明、正确与错误的代码示例及注意事项:
odoo-manifest.md
odoo-orm-models.md
odoo-orm-fields.md
odoo-orm-decorators.md
odoo-orm-recordsets.md
odoo-actions.md
odoo-performance.md
odoo-testing.md
odoo-mixins.md
每个文件包含:
  • 该规则在Odoo 17.0中的重要性
  • 错误代码示例及解释(
    # ❌ WRONG
  • 正确代码示例及解释(
    # ✅ CORRECT
  • 决策树与边缘情况

Full Compiled Document

完整编译文档

For the complete guide with all rules, patterns, and examples expanded, including global coding guidelines and skill routing table:
AGENTS.md
如需包含所有规则、模式及扩展示例的完整指南,包括全局编码规范与技能路由表,请查看:
AGENTS.md