Odoo 19 技术教程:如何在 Odoo 19 中使用模型属性

如何在 Odoo 19 中使用模型属性

你是否曾思考过,是什么让 Odoo 模型具备如此出色的适应性和高效性?无论你已经在使用 Odoo 进行开发,还是刚刚开始探索,熟练掌握模型属性都将为你带来颠覆性的提升。在 Odoo 19 中,这些属性是业务逻辑的基石------它们控制着数据的存储方式、系统的响应逻辑,甚至记录在界面中的展示形式和行为。理解这些属性,你就能真正掌握定制化应用的核心能力。

你可以将模型属性理解为指导 Odoo 处理数据的指令集。它们定义了数据是存储到数据库、保留在内存中快速处理,还是作为其他模型继承的基础结构。这套灵活的系统,正是 Odoo 成为强大且可定制化业务应用开发平台的核心原因之一。


Odoo 模型的三大核心类型

在深入学习各类属性之前,我们先了解构成所有 Odoo 应用基础的三种核心模型类型:

1. 普通模型(Model)------ 应用的核心主力

持久化存储到数据库的普通模型,是 Odoo 应用的基础核心。这类模型代表你的核心业务实体,例如客户、产品、销售订单和发票。通过这些模型创建的每一条记录都会永久保存在数据库中,且跨会话持久生效。当你创建客户记录或生成发票时,就是在使用普通模型。

适用场景:客户档案、产品目录、销售订单、会计分录------所有需要永久存储和查询的数据。

python 复制代码
# -*- coding: utf-8 -*-
class LibraryBook(models.Model):
   _name = 'library.book'  # 模型唯一技术名称
   _description = '图书馆图书管理'  # 可读的模型名称
   _table = 'library_book'  # 自定义数据库表名(可选)
   _rec_name = 'name'  # 用作记录展示名称的字段
   _order = 'name asc'  # 默认排序规则
   _inherit = []  # 继承的现有模型(如需)
   _inherits = {}  # 委托继承(父模型: 关联ID字段)
   _abstract = False  # 抽象模型设为 True
   _transient = False  # 临时向导模型设为 True
   _auto = True  # 自动创建数据库表
   _register = True  # 在 ORM 中注册模型
   _parent_name = 'parent_id'  # 层级关系关联字段
   _parent_store = False  # 启用树形结构优化
   _active_name = 'active'  # 归档/取消归档使用的字段
   _check_company_auto = True  # 强制多公司数据一致性
   _allow_sudo_commands = True  # 允许对该模型执行 sudo 操作
   _rec_names_search = ['name', 'isbn']  # 多对一字段搜索时使用的字段
   # SQL 视图相关(仅当 _auto = False 时使用)
   _table_query = None  # 为基于视图的模型定义 SQL 查询
   _depends = {}  # SQL 视图模型的依赖关系
   # 字段定义
   name = fields.Char(string="图书名称", required=True)
   isbn = fields.Char(string="ISBN编号")
   author = fields.Char(string="作者")
   active = fields.Boolean(string="启用", default=True)
   parent_id = fields.Many2one(
       'library.book',
       string="父级图书",
       ondelete='cascade'
   )

2. 临时模型(TransientModel)------ 临时数据助手

临时模型专为临时数据设计,用于完成特定任务后自动清理。这类模型会将数据存储在数据库中,但自带自动销毁机制------系统会自动清理旧记录,避免数据库冗余。它们非常适合向导、临时计算和用户交互表单。

适用场景:向导表单、临时报表、数据导入/导出助手、无需永久存储的用户偏好弹窗。

python 复制代码
# -*- coding: utf-8 -*-
class BookReportWizard(models.TransientModel):
   _name = 'library.book.report.wizard'  # 模型唯一名称
   _description = '图书报表生成向导'  # 展示名称
   _table = 'library_book_report_wizard'  # 自定义表名(可选)
   _rec_name = 'name'  # 界面中展示的字段
   _order = 'id desc'  # 默认排序
   _inherit = []  # 经典继承(向导中极少使用)
   _inherits = {}  # 委托继承(不推荐在此使用)
   _abstract = False  # 非抽象模型
   _transient = True  # 标记为临时模型
   _auto = True  # 自动创建表
   _register = True  # 在 ORM 中注册
   _transient_max_count = 1000  # 保留的最大记录数
   _transient_max_hours = 1.0  # 自动删除超过 X 小时的记录
   _parent_name = None  # 向导中不使用
   _parent_store = False  # 无层级结构
   _active_name = 'active'  # 可选的归档支持
   _check_company_auto = False  # 通常无需配置
   _allow_sudo_commands = True  # 允许 sudo 操作
   _rec_names_search = ['name']  # 搜索字段
   # SQL 相关(临时模型不使用)
   _table_query = None
   _depends = {}
   # 字段定义
   name = fields.Char(string="向导名称")
   date_from = fields.Date(string="开始日期")
   date_to = fields.Date(string="结束日期")
   active = fields.Boolean(string="启用", default=True)

3. 抽象模型(AbstractModel)------ 可复用的蓝图模板

抽象模型是实现代码高效复用的核心。它们不会创建独立的数据库表,而是作为其他模型继承的基础结构。你可以将其理解为可复用组件,提供共享的字段、方法和行为,让多个模型无需重复编写代码即可使用相同功能。

适用场景:邮件线程、网站发布功能等通用逻辑,或多个模型需要实现的共享行为。

python 复制代码
# -*- coding: utf-8 -*-
class TimestampMixin(models.AbstractModel):
   _name = 'timestamp.mixin'  # 唯一技术名称
   _description = '时间戳混合模型(通用日期字段)'  # 展示名称
   _table = None  # 抽象模型不创建表
   _rec_name = None  # 抽象模型通常无需配置
   _order = None  # 无默认排序(不直接使用)
   _inherit = []  # 可继承其他混合模型(如需)
   _inherits = {}  # 委托继承(抽象模型极少使用)
   _abstract = True  # 标记为抽象模型
   _transient = False  # 非临时模型
   _auto = False  # 不创建数据库表
   _register = True  # 注册模型以便被继承
   _parent_name = None  # 无层级关系
   _parent_store = False  # 无树形结构优化
   _active_name = None  # 无归档概念
   _check_company_auto = False  # 混合模型无需配置
   _allow_sudo_commands = True  # 默认允许 sudo 操作
   _rec_names_search = []  # 不使用
   # SQL 相关(不适用)
   _table_query = None
   _depends = {}
   # 通用可复用字段
   created_on = fields.Datetime(
       string="创建时间",
       default=fields.Datetime.now
   )
   updated_on = fields.Datetime(
       string="最后更新时间"
   )

模型属性完整详解

了解模型类型后,我们来学习全套模型属性,这些属性让你精准控制模型的行为:

核心标识属性

  • _name (字符串) :模型的唯一标识符,采用点分隔格式。这是模型的唯一标识,在整个 Odoo 系统中必须唯一。示例:'sale.order''res.partner''product.template'
  • _description (字符串 | None) :模型的可读名称,显示在用户界面、菜单和错误提示中。虽为可选配置,但对用户体验至关重要。示例:'销售订单''客户''产品模板'
  • _module (字符串 | None):标识该模型所属的 Odoo 模块,用于管理模块依赖和结构。通常由框架自动设置。
  • _custom (布尔值) :仅当模型通过 Odoo 工作室或自定义开发创建时,设为 True。用于区分 Odoo 核心模型和自定义扩展模型。

数据库与表管理

  • _auto (布尔值) :控制 Odoo 是否自动为模型创建数据库表。如需手动创建表或使用数据库视图,设为 False。抽象模型默认值为 True
  • _table (字符串):指定数据库中使用的精确 SQL 表名。未设置时,Odoo 会自动将模型名称中的点替换为下划线生成表名。
  • _table_query (SQL 语句 | 字符串 | None):将模型内容定义为 SQL 表达式,本质是创建数据库视图而非普通表。非常适合复杂报表模型。
  • _table_objects (字典):高级属性,用于定义与模型关联的 SQL/表对象,适用于复杂数据库操作和性能优化。

模型行为标记

  • _register (布尔值) :控制模型是否注册到 Odoo 模型注册表并被框架识别。无需实例化的工具类可设为 False
  • _abstract (布尔值):标记模型为抽象模型。抽象模型不创建数据库表,仅用于被其他模型继承,实现功能共享。
  • _transient (布尔值):标记模型为临时模型,其记录会在一段时间后被系统自动清理。适用于临时数据和向导。

继承与组合

  • _inherit (字符串 | 字符串列表 | 元组) :定义 Python 风格的继承。设置了 _name 时,代表继承的父模型;未设置 _name 时,直接扩展现有的模型,添加新字段和方法。
  • _inherits (冻结字典):通过字典(父模型名称: 外键字段名)实现基于组合的继承。新模型可直接访问父模型的所有字段,但数据存储在关联的记录中。
  • _inherit_children (有序集合):框架自动维护的子模型集合,记录继承自当前模型的所有子模型。用于框架内部的继承解析。

用户界面与展示

  • _rec_name (字符串 | None) :在选择列表、多对一字段和面包屑导航中展示记录名称的字段。若存在 name 字段,默认使用该字段;否则使用第一个字段。
  • _rec_names_search (字符串列表 | None):用户在多对一字段或全局搜索中输入关键词时,用于检索的字段列表。支持多字段搜索,提升用户体验。
  • _order (字符串) :未指定排序规则时,记录的默认排序方式。使用 SQL 的 ORDER BY 语法。示例:'name asc''create_date desc, name'
  • _fold_name (字符串):用于判断看板视图分组是否折叠的字段名。通常是布尔字段,控制看板列的展开/折叠状态。

层级结构

  • _parent_name (字符串):创建同模型记录父子关系的多对一字段。支持组织结构图、分类树等层级结构。
  • _parent_store (布尔值) :通过计算 parent_path 字段,启用层级数据的优化存储。大幅提升大型层级数据集的 child_ofparent_of 域操作性能。

记录归档管理

  • _active_name (字符串 | None) :自动设置为 activex_active,标识用于记录归档/取消归档的字段。启用的记录显示在普通视图中,归档记录隐藏但不会被删除。

本地化与翻译

  • _translate (布尔值):控制模型字段是否包含在翻译导出文件中。该属性为遗留功能,未来版本可能会被废弃。

安全与权限控制

  • _check_company_auto (布尔值) :自动对标记了 check_company=True 的关联字段验证公司一致性。防止多公司环境下的数据泄露问题。
  • _allow_sudo_commands (布尔值) :控制使用 sudo()with_user() 时,一对多、多对多操作是否可指向该模型。安全敏感模型应设为 False,防止权限提升攻击。

高级性能优化

  • _depends (冻结字典) :为 SQL 视图驱动的模型定义依赖关系,指定触发更新的模型字段。格式:{模型名称: 字段名称列表}。用于缓存失效和数据库同步。

Odoo 19 中的扩展继承

python 复制代码
class SaleOrder(models.Model):
    """
    该类扩展现有的 `sale.order` 模型,添加自定义测试字段
    技术说明:
        - 使用经典继承(_inherit)
        - 不创建新模型,仅扩展现有模型
    """
    _inherit = 'sale.order'  # 扩展现有的模型
    test_field = fields.Char(
        string="测试字段",
        help="这是一个测试字段。",
    )

Odoo 19 中的委托继承

python 复制代码
class LibraryBook(models.Model):
    """
    该模型演示通过 `_inherits` 实现与 `product.template` 的委托继承
    核心概念:
        - `_inherits` 通过多对一字段关联模型
        - 可直接访问父模型的字段
        - 数据存储在多张表中
    """
    _name = 'library.book'
    _description = '关联产品模板的图书馆图书'
    _inherits = {
        'product.template': 'product_tmpl_id'
    }
    product_tmpl_id = fields.Many2one(
        'product.template',
        string="关联产品",
        required=True,
        ondelete='cascade',
        help="将图书与产品模板记录关联。"
    )
    author = fields.Char(
        string="作者",
        help="图书作者姓名。",
        required=True,
        index=True,
    )
    isbn = fields.Char(
        string="ISBN编号",
        help="图书唯一标识。",
        copy=False,
        index=True,
    )

经典继承示例

python 复制代码
class Inheritance0(models.Model):
   _name = 'inheritance.0'
   _description = '基础继承模型'
   name = fields.Char()
   def call(self):
       return self.check("模型 0")
   def check(self, s):
       return "这是 {} 记录 {}".format(s, self.name)

class Inheritance1(models.Model):
   _name = 'inheritance.1'
   _inherit = ['inheritance.0']
   _description = '扩展继承模型'
   def call(self):
       return self.check("模型 1")

总结

掌握这些模型属性,你就能创建不仅功能完善,而且经过性能优化、安全可靠、用户友好的模型。每个属性都在 Odoo 应用架构中承担特定作用------从赋予模型身份的 _name,到优化复杂场景性能的高级属性 _depends

在 Odoo 19 中,模型属性远不止基础配置那么简单,它们能将普通的 Python 类转化为功能完整的业务组件。无论你是添加简单的自定义字段,还是设计跨多公司的复杂架构,理解这些属性都能为你提供构建可靠、可扩展解决方案所需的控制力和灵活性。

随着 Odoo 开发经验的积累,你会发现这些属性不仅仅是技术细节------它们是真实业务流程在系统中落地的基础。无论是小型企业还是大型集团,每一次流畅的 Odoo 项目实施,背后都离不开对这些模型属性的精准、合理运用。

相关推荐
odoo中国1 天前
Odoo 19 制造模块功能:制造模块中废品管理操作指南
制造·odoo·odoo19·生产废品管理·生产报废管理·报废流程
odoo中国2 天前
Odoo 19 中升级(迁移)脚本的使用方法
odoo·odoo19·odoo技术·升级脚本·迁移脚本
odoo中国3 天前
Odoo 19 安全完整解析:多层防护守护企业核心数据
安全·odoo·数据备份·数据保护·用户权限·odoo19·用户访问规则
odoo中国5 天前
Odoo 19 功能性报表解析:如何高效使用补货报表
odoo·odoo19·库存报表·补货报表
odoo中国5 天前
如何在 Odoo 19 中创建序列
odoo·odoo19·自定义单据序列
odoo中国14 天前
Odoo 19 财务功能概述:财务模块中的定期存货计价(期末库存结转)
odoo·库存管理·财务管理·odoo19·库存计价·库存估值·期末库存结转
odoo中国16 天前
Odoo 19 库存功能实操:产品包装的设置与管理
odoo·仓库管理·odoo19·包装设置与管理
云草桑16 天前
Odoo 19.0 Docker Desktop快速部署 和Ubuntu24上安装1panel面板
运维·docker·容器·odoo
odoo中国21 天前
Odoo 19 采购功能:如何创建与管理产品类别,实现更智能的采购
odoo·odoo19·产品类别·采购类别·产品类别配置