筑基期:掌握Odoo基础核心知识点01

Odoo 所有数据模型均继承自基础模型类,核心分为三大类:持久化模型、临时模型、抽象模型。其中持久化模型和临时模型是业务开发中最常用的两大核心模型,抽象模型主要作为基类用于逻辑复用,以下结合具体用法、场景及示例,系统梳理Odoo开发核心知识点。

一、Odoo核心数据模型(三大类)

(一)核心两大业务模型:models.Model vs models.TransientModel

  1. models.Model ------ 持久化业务模型(开发主力)

核心概念

  • Odoo 最常用、最核心的模型类,是业务开发的核心载体。

  • 数据会永久存储在数据库中,系统会自动为该模型创建真实的数据库表。

  • 支持增删改查、数据关联、权限控制、视图配置、工作流等所有Odoo核心功能。

  • 自带完整的ORM(对象关系映射)能力,可直接通过ORM方法操作数据。

适用场景(必须使用该模型)

所有需要长期保存、后续需查询、统计、关联的业务核心数据,具体包括:

  • 基础业务数据:客户、供应商、产品、订单、发票等。

  • 组织架构数据:员工、部门、岗位等。

  • 业务流程数据:库存记录、生产工单、采购单等。

  • 自定义业务模块的核心数据表,以及任何需要长期留存的业务数据。

代码示例

from odoo import models, fields

class SaleOrder(models.Model):

数据库表名(必填):sale_order(默认与_name一致,可通过_table修改)

_name = 'sale.order'

模型描述(必填),用于文档和界面显示

_description = 'Sales Order'

复制代码
# 持久化字段(数据永久存储在数据库)
name = fields.Char(string='Order Number', required=True)  # 订单编号(必填)
partner_id = fields.Many2one('res.partner', string='Customer')  # 关联客户(多对一)
amount_total = fields.Float(string='Total Amount')  # 订单总金额(小数)
  1. models.TransientModel ------ 临时模型 / 向导模型

核心概念

  • 数据临时存储,Odoo会通过定时任务定期清理表中数据,不长期留存。

  • 虽然也会创建数据库表,但仅用于存储临时操作数据,不存储业务核心数据。

  • 专门用于向导(Wizard)、弹窗交互、临时操作、批量处理等场景。

  • 无权限控制、无复杂业务状态、无复杂数据关联,功能相对简单。

适用场景(必须使用该模型)

仅需要临时交互、一次性操作,操作完成后数据无需留存的功能,具体包括:

  • 数据导入/导出向导(如批量导入客户、导出订单数据)。

  • 批量操作:批量修改数据、批量删除记录、批量发送邮件等。

  • 弹窗交互:报表参数配置弹窗、打印格式配置弹窗等。

  • 一次性操作:操作确认弹窗、临时表单填写等。

代码示例

from odoo import models, fields

class SaleOrderBatchSend(models.TransientModel):

临时模型表名(必填)

_name = 'sale.order.batch.send'

_description = 'Batch Send Sales Order' # 模型描述

复制代码
# 临时字段,操作完成后会被系统自动清理
order_ids = fields.Many2many('sale.order', string='Orders')  # 关联需要发送的订单(多对多)
send_note = fields.Text(string='Send Note')  # 发送备注(多行文本)

def action_send_orders(self): 
    # 执行业务逻辑(批量修改订单状态),执行完成后数据无需留存
    self.order_ids.write({'state': 'sent'})
    return {'type': 'ir.actions.act_window_close'}  # 关闭向导弹窗
  1. models.AbstractModel ------ 抽象模型(仅作为基类)

核心概念

  • 不创建数据库表,仅作为继承基类使用,无法直接存储数据。

  • 用于封装多个模型共用的公共字段、公共方法,实现代码复用,减少冗余。

  • 不能创建视图、不能直接实例化使用,只能被其他模型继承。

适用场景

当多个模型需要共用相同的字段或方法时,抽离公共逻辑,统一封装为抽象模型,具体包括:

  • 公共基础字段:创建时间、修改时间、创建人、修改人、是否激活等。

  • 公共业务方法:通用数据校验、通用格式转换、公共查询逻辑等。

代码示例

from odoo import models, fields

class BaseCommon(models.AbstractModel):

抽象模型标识(必填)

_name = 'base.common'

_description = 'Base Common Model' # 模型描述

复制代码
# 公共字段:所有继承该抽象模型的模型,都会自动拥有这些字段
create_date = fields.Datetime(string='Create Time', default=fields.Datetime.now)  # 创建时间(默认当前时间)
create_uid = fields.Many2one('res.users', string='Creator')  # 创建人(关联系统用户)
active = fields.Boolean(string='Active', default=True)  # 是否激活(默认勾选)

继承抽象模型,自动获得公共字段

class Product(models.Model):

_name = 'product.product' # 产品模型表名

_inherit = 'base.common' # 继承公共抽象模型,无需重复定义公共字段

二、Odoo模型方法命名规范(核心常识)

Odoo模型中方法的命名的核心原则:根据调用者(框架/用户)区分,以下是具体规范和说明:

(一)方法调用区分

  • 以 _ 开头的方法:Odoo框架专用的内部方法,由框架自动调用,不建议手动调用。

  • 不以 _ 开头的方法:对外暴露的业务方法,用于用户操作(如按钮点击)、界面触发、外部调用。

(二)特殊方法命名规则(必记)

  • 计算字段方法:必须以 compute 开头,格式为 _compute_字段名,用于计算字段的逻辑实现。

  • 反向计算字段方法:以 inverse 开头,用于可手动修改的计算字段(反向写入数据)。

  • 默认值方法:以 default 开头,用于设置字段的默认值。

  • 约束校验方法:以 check 开头,用于自定义数据校验逻辑。

(三)私有方法约定

  • 以 _ 开头的方法,同时约定为私有方法,仅在当前模型类内部使用,不对外暴露调用。

  • 计算方法、框架内部方法,均需加 _ 前缀,避免被外部误调用。

一句话总结

Odoo框架自己使用、自动调用的方法,全部带下划线 _;给用户、界面、外部使用的方法,不带下划线。

三、Odoo开发必背8大装饰器(核心重点)

装饰器用于修饰模型方法,定义方法的作用范围、触发时机和功能,以下是业务开发中常用的8种装饰器,重点掌握前5种:

  1. @api.multi(最常用)
  • 作用:使方法支持处理多条记录(self为记录集,可循环遍历)。

  • 适用场景:按钮点击、业务逻辑方法、界面触发的动作。

  • 注意事项:Odoo12及以前版本,所有处理多条记录的方法必须添加;后续版本可省略,但建议保留以保证兼容性。

  1. @api.model
  • 作用:方法不操作已有记录,仅针对模型本身进行操作(self不指向任何具体记录)。

  • 适用场景:创建新记录、搜索记录、数据统计、定时任务(scheduled action)、公共工具方法。

  1. @api.one(废弃,极少用)
  • 作用:方法仅处理单条记录(self为单条记录,无需循环)。

  • 注意事项:目前已被@api.multi替代,业务开发中基本不用,避免使用。

  1. @api.depends(字段1, 字段2...)
  • 作用:监听指定字段,当这些字段的值发生变化时,自动重新计算当前方法(用于计算字段)。

  • 适用场景:compute=xxx的计算字段,必须搭配 _compute_xxx 格式的方法使用。

  • 注意事项:方法名必须以 compute 开头,与计算字段名对应。

  1. @api.constrains(监控字段)
  • 作用:在记录保存前,自动校验监控字段的值,若不满足校验条件,报错并阻止保存。

  • 适用场景:日期合理性校验、金额范围校验、状态校验、数据唯一性校验等。

  • 特点:自带@api.multi功能,无需额外添加,可处理多条记录。

  1. @api.onchange(字段)
  • 作用:在前端界面修改指定字段时,立即触发该方法(无需保存记录),实现界面联动。

  • 适用场景:选择客户后自动带出客户地址、修改商品数量后自动计算金额、选择分类后过滤商品列表等。

  • 特点:仅作用于单条记录,self为当前编辑的单条记录,无需循环。

  1. @api.depends + inverse(极少用)
  • 作用:用于可手动修改的计算字段,实现"计算字段反向写入"(即手动修改计算字段值时,同步更新其依赖的字段)。

  • 适用场景:特殊业务场景,普通开发中极少用到。

  1. @api.noguess(几乎不用)
  • 作用:底层框架控制,用于禁止Odoo自动推断方法的参数和返回值。

  • 适用场景:仅底层开发使用,业务开发中永远不会碰到,无需深入掌握。

装饰器快速对应表(必记)

  • 按钮动作、业务方法 → @api.multi

  • 新建记录、搜索、统计、定时器 → @api.model

  • 计算字段自动计算 → @api.depends

  • 记录保存前校验 → @api.constrains

  • 前端界面联动 → @api.onchange

四、常用代码片段解析

  1. 视图查找:self.env.ref('外部ID')

self.env.ref('emabc_expense.wizard_emabc_expense_pay_form')

  • self.env:当前模型的环境对象(Environment),包含当前用户、数据库、上下文等信息,是Odoo开发中获取各类资源的核心入口。

  • ref()方法:通过视图的外部ID(XML ID)查找对应的视图记录,外部ID格式为"模块名.视图ID"。

  • 'emabc_expense.wizard_emabc_expense_pay_form':视图的外部ID,其中emabc_expense是模块名,wizard_emabc_expense_pay_form是视图的ID。

  1. 获取记录ID:.id
  • 用法:在查找记录后,通过 .id 可获取该记录在数据库中的唯一ID(主键)。

  • 示例:self.env.ref('模块名.视图ID').id,用于获取视图的数据库ID,常用于弹窗跳转、视图渲染等场景。

五、Odoo常用字段类型(10种,必记)

字段是模型的核心组成部分,用于定义数据的类型和属性,以下是业务开发中最常用的10种字段类型,按类别划分,方便记忆:

(一)基础字段(7种,最常用)

  • fields.Char():单行文本,用于存储短文本信息,如名字、编号、手机号等。

  • fields.Text():多行文本,用于存储长文本信息,如备注、描述、详细说明等。

  • fields.Integer():整数,用于存储无小数的数值,如数量、天数、个数等。

  • fields.Float():小数,用于存储有小数的数值,如金额、比例、重量等(可通过digits参数设置小数位数)。

  • fields.Boolean():勾选框,用于存储布尔值(是/否),如是否激活、是否审核等(默认值为False)。

  • fields.Date():日期,用于存储日期(格式:2025-01-01),如订单日期、出生日期等。

  • fields.Datetime():日期时间,用于存储具体的日期和时间(格式:2025-01-01 12:00:00),如创建时间、修改时间等。

(二)货币/金额字段(1种)

  • fields.Monetary():金额字段,专门用于存储货币金额,需搭配currency_id字段(指定货币类型)使用,如订单金额、付款金额等。

(三)关联字段(2种,最重要)

关联字段用于实现不同模型之间的数据关联,是Odoo业务逻辑联动的核心,必须重点掌握:

  • fields.Many2one():多对一关联,即"多个当前记录对应一个关联记录",如多个订单对应一个客户、多个员工对应一个部门。

  • fields.One2many():一对多关联,即"一个当前记录对应多个关联记录",需配合Many2one使用(反向关联),如一个客户对应多个订单、一个部门对应多个员工。

  • fields.Many2many():多对多关联,即"多个当前记录对应多个关联记录",如多个订单对应多个产品、多个员工对应多个角色。

补充:字段常见参数(高频使用)

所有字段括号内可添加参数,用于配置字段的显示和功能,常用参数如下:

  • string:字段在界面上的显示名称(必填,如string='Order Number')。

  • required:是否必填(True/False),必填字段未填写时无法保存记录。

  • default:字段默认值(如default=fields.Datetime.now、default=True)。

  • readonly:是否只读(True/False),只读字段无法在界面上修改。

  • help:字段提示信息,鼠标悬浮时显示,用于说明字段用途。

  • digits:小数位数(仅用于Float、Monetary字段,如digits=(10,2)表示保留2位小数)。