创建模型
模型属性:模型类可以使用一些属性来控制它们的一些行为:
_name :创建odoo模型的内部标识符,必含项。
_description :当用户界面显示模型时,一个方便用户的模型记录标题。
_order :当浏览模型记录或者显示在列表视图时,设置默认顺序。
_rec\_name:用来指出引用关联字描述记录的字段,例如多对一关系。 默认情况下,它使用name字段,这是模型中常见的字段。但是这个属性允许我们使用任何其他字段来实现这个目的。
_table:用来支持模型的数据库表名。通常,它是左自动计算,是下划线取代点的模型名称,但也可以设置特定的表名。
_inherit :继承。
_inherits :嵌入式继承。
Odoo还提供了另外两种模型类型:瞬态模型和抽象模型。
- 瞬态模型
基于models.TransientModel
类,通常用于向导。 它们的数据仍然存储在数据库中,但是临时的,一个清理作业定期从这些表中清除旧数据。
- 抽象模型
基于models.AbstractModel
类, 不存储数据,不会在数据库创建表。 抽象模型作为可重用的功能集,利用Odoo的继承功能,混入到其他模型。通常用于定义接口或者用作报表模型。
继承和扩展
Odoo提供三种不同的机制来以模块化的方式继承模型:
- 从已有模型新建一个模型,对复制的模型新增信息,但保留原模块为原样
- 在原处继承模块中定义的模型,替换原来的版本
- 你本来就是该模型的一些字段为它包含的记录
经典继承
在共同使用_inherit
和 _name
属性时, Odoo使用已有模型(通过_inherit
)作为基础新建一个模型。新模型从基础获取所有字段、方法及元信息(defaults & al) 。
扩展
在使用_inherit
但保留 _name
时,新模型替换已有模型,基本是在原地进行扩展。这对于向(其它模块中所创建的)已有模型新增字段或方法、或是自定义或重新配置它们(例如修改默认排序)都非常有用:
代理
第三种继承机制提供更丰富的灵活性(可在运行时进行修改),但功能更少;使用_inherits
模型代理当前模型中未找到的任意字段查询到“子”模型中。代理通过 Reference
字段自动在父级模型中设置。
最主要的区别是,在使用代理时,模型拥有它而非是它,转换组合中的关联而非继承:
重点字段
_class _odoo.fields.Many2one
这一字段的值是一个大小为0(无记录) 或 1 (单条记录)的记录集。
- comodel_name (
str
) – 目标模型Mandatory
除关联或扩展字段以外的名称。
_class _odoo.fields.One2many
该字段的值是comodel_name
中所有记录的记录集,这样inverse_name
字段等于当前记录。
_class _odoo.fields.Many2many
Many2many字段,这类字段的值是记录集。参数
- comodel_name – 在关联字段及字段继承以外的情况下必填的目标目标模型(字符串)名
- relation (
str
) – 数据库中存储关联的可选数据表名称
关联字段
计算字段的一种特殊情况是_关联_(代理)字段,它提供当前记录的子字段值。它们通过设置related
参数进行定义并可以像普通字段那样进行存储:
nickname = fields.Char(related='user_id.partner_id.name', store=True)
默认,关联字段的值不在数据库中存储。和计算字段类似,添加store=True
属性来对其进行存储。关联字段在修改依赖时会自动重新计算。
常用参数
- copy (
bool
) – 在复制记录时是否应拷贝该字段值(默认: 普通字段为True
,one2many
及计算字段,包含属性字段及关联字段,为False
) - store (
bool
) – 字段是否存储在数据库中 (默认:True
, 对于计算字段为False
) - ondelete,可选值为"cascade"和"null",缺省值为"null",表示one端的record被删除后,many端的record是否级联删除。
set null: 当b中删除记录时,modelA中相关记录的a=null
cascade: 当b中删除记录时,modelA中相关记录也全部删除
restrict: 当b中删除记录时,如果modelA中存在对应记录,则无法操作 b 的删除
- digits定义数字总长和小数部分的位数 如:
digits=(12,6)
计算字段
- inverse (
str
) – 推导字段的方法名(可选参数) - search (
str
) – 实现对字段搜索的方法名 (可选参数) - related (
str
) – 字段名的序列。可以简记为“带出字段”,由当前模型的某个关联类型字段的某个字段带出值。
方法装饰器
Odoo自带的api装饰器主要有:model,multi,one,constrains,depends,onchange,returns 七个装饰器。
- model
objectivec 此时的self仅代表模型本身,不含任何记录信息。
odoo.api.depends(_\*args_) 针对compute使用
触发条件
1、compute字段值需要读取(内存中没有)
2、depends里的字段值改变
返回一个指定对“compute”方法(针对新模式函数字段)依赖字段的装饰器。每个参数必须为一个包含点号分隔的字段名序列的字符串:
@api.depends('partner_id.name','partner_id.is_company')
def _compute_pname(self):
odoo.api.constrains(_*args_)
装饰约束检查器。
每个参数必须为用于检查中的字段名:
@api.constrains('name', 'desc')
def _check_description(self):
当name、desc保存时或者修改时都会进入该校验,对命名字段进行修改的记录进行调用。
在验证失败时应该会抛出ValidationError
。
odoo.api.onchange(_*args_)
返回装饰给定字段onchange方法的装饰器。
设置store=True
会将它们存储在数据库中并自动启用搜索, ps:项目中有个筛选条件是计算字段,若不设置store为True则搜不到。
Environment
Environment
存储各种由 ORM 所使用的上下文数据:数据库游标(用于数据库查询)、当前用户 (用于访问权限检查) 及当前上下文 (存储任意metadata)。环境中还存储缓存。
所有的记录集都有一个环境,它是不可变的,可使用env
进行访问并授权给:
- 当前用户(
user
) - 游标 (
cr
) 数据库游标对象,用于查询数据库 - 超级用户标记 (
su
) - 或上下文(
context
) -
Environment.ref(_xml_id_, _raise_if_not_found=True_)
返回响应指定xml_id
的记录。
常用ORM方法
Create/update
Model.create(_vals_list_) → records
为模型创建新记录。
新记录使用vals_list
字典列表中的值进行初始化,必要时通过 default_get()
。
参数
vals_list –模型字段的值,字典列表的形式:
[{'field_name': field_value, ...}, ...]
Model.copy(_default=None_)
复制记录self
使用默认值进行更新
参数 default (dict
) – 在所复制记录的原始值中重载字段值字典,例如:{'field_name': overridden_value, ...}
Model.write(_vals_)
通过所提供值更新当前集合中的所有记录。
- 特殊用法
One2many
和 Many2many
使用特殊“命令”格式来操作存储在该字段或与该字段相关联的记录的集合中。
这个格式是一个序列执行的三元列表,每个三元元素是一个对一组记录执行的命令。并非所有命令适用所有场景。可用的命令有:
(0, 0, values)
新增由所提供的`value`字典所创建的记录。
(1, id, values)
使用`values`中的值更新已有的 id为 `id`的记录。不能用于 [`create()`](https://alanhou.org/odoo-13-orm-api/#odoo.models.Model.create)。
(2, id, 0)
从集合中移除id为`id`的记录,然后(从数据库中)删除它。不能在[`create()`](https://alanhou.org/odoo-13-orm-api/#odoo.models.Model.create)中使用。
(3, id, 0)
集合中移除id为`id`的记录,但不删除它。不能用于 [`create()`](https://alanhou.org/odoo-13-orm-api/#odoo.models.Model.create)。
(4, id, 0)
向集合添加id为 `id`的已有记录。
(5, 0, 0)
从集合中删除所有记录,等价于对所有记录显式的调用于命令`3`。不能用于 [`create()`](https://alanhou.org/odoo-13-orm-api/#odoo.models.Model.create)。
(6, 0, ids)
通过`ids` 列表替换掉集合中所有已有记录list, 等价于对`ids`中的每个`id`执行命令`4`然后执行命令`5`。
Search/Read
Model.browse([_ids_]) → records
在当前环境中返回以 ids为参数的记录集。
参数 ids ([int
] or
[list
](
[int
]or `None
) – id(s)
Model.search(_args[, offset=0][, limit=None][, order=None][, count=False]_)
self.env['ir.model.data'].sudo().search_read(domain, ['module', 'name', 'res_id'])
根据args
搜索域搜索记录。
参数
- args– 一个搜索域。使用空列表来匹配所有记录。
- offset (
int
) – 要忽略的结果数 (默认值: none) - limit (
int
) – 返回的最大记录数(默认值: all) - order (
str
) – 排序字符串 - count (
bool
) – 若为True, 仅计数并返回所匹配记录数 (默认值: False)
Model.search_count(_args_) → int
返回当前模型中匹配所提供域的记录数。
Model.unlink()
删除当前集合的记录
Model.ensure_one()
验证当前记录集存有单条记录。