Odoo ORM链式字段访问record.company_id.name语法含义咨询
Odoo ORM链式字段访问原理解答
你疑惑的record.company_id.name链式写法,本质是Odoo ORM对关系字段的封装特性,和原生SQL直接访问表字段的逻辑有区别,具体拆解如下:
各层级含义拆解
record不是表名,是某张业务表的单条记录对象,比如示例中record可以是销售订单(对应底层表sale_order)的某一条订单记录company_id是当前记录对应表上的多对一(Many2one)关系字段:这类字段在数据库底层仅存储关联表的主键ID作为外键,但Odoo ORM访问该字段时,不会直接返回ID值,而是自动查询关联表(这里是公司表res_company),返回对应关联记录的对象- 既然
record.company_id已经拿到了公司表的单条记录对象,自然可以继续用点运算符访问公司表本身的name字段,就形成了record.company_id.name的链式写法
对应底层表结构示例
你可以对照两张表的底层结构理解:
- 当前记录所属表(以销售订单表
sale_order为例)
| 字段名 | 字段类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| name | varchar | 订单编号 |
| company_id | int | 外键,关联res_company表的id字段 |
- 关联表(公司表
res_company)
| 字段名 | 字段类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| name | varchar | 公司名称 |
| phone | varchar | 公司联系电话 |
等价原生SQL逻辑
如果用原生SQL实现和record.company_id.name等价的查询,需要写联表语句:
SELECT res_company.name FROM sale_order LEFT JOIN res_company ON sale_order.company_id = res_company.id WHERE sale_order.id = [当前record的主键ID]
Odoo ORM将上述联表查询逻辑做了封装,无需手动编写联表语句,直接通过链式访问就能拿到关联表的字段值。
拓展说明
除了多对一字段外,Odoo另外两类关系字段也遵循类似逻辑:
- 一对多(One2many)、多对多(Many2many)字段访问时会返回多条记录的集合对象,需要遍历或指定索引后才能访问具体字段,比如
record.order_line[0].name就是取订单关联的第一条订单行的名称 - 如果关系字段为空(没有关联记录),链式访问会直接返回空值,不会抛出字段不存在的异常
内容的提问来源于stack exchange,提问作者user3808269
相关产品推荐
相关产品推荐

