Model
模型定义,也就 基于 odoo.models.Model 或者 odoo.models.AbstractModel
以及 odoo.models.TransientModel 继承出来的 模型, 它是 实实在在的 python Class
它会被ORM 转化为 ModelClass,一个模型只有一个对应的 ModelCLass, 存在多个模型定义时,最终都合并到同一个 ModelClass
Odoo 模块作为python package 被引入的时候,会运行 MetaModel 的魔术逻辑,往 models.MetaModel.module_to_models 登记
ModelClass
在 build_model() 时,首先将 Model 实例化为 ModelClass , 然后 再被实例化为 model,并执行 model 的 __init__() 方法,完成 model 的初始化
ModelClass 的名称格式为 例如 <class 'odoo.api.ir.model.constraint'>
RecordSet
通过 _browse() 方法,将 ModelClass 和 env, 以及 ids 传递进去,从而获取 recordset
先实例化 model 为 recordset , 再将 env 绑定给 recordset
recordset 的名称格式为 例如 ir.model.constraint()
如果 ids 是空值,则得到空记录集, 空记录集称之为model
它们之间的关系,如图所示
class1, class2, class3 是用户自定义的 Model, 均继承自 odoo.models.Model
Registry
每一个数据库都会有一个 registry, 在加载数据库的时候,新建registry。
然后扫描模块列表,按照依赖关系,逐个加载Odoo 模块,逐个将 Odoo 模块加载到 registry, registry 使用它的 load() 方法 从models.MetaModel.module_to_models 读取出 Model,并 调用 build_model() 将其实例化为 ModelClass
modelClass 建立完毕之后,也就是 registry 完成 load_moudles() 之后, 进行下一阶段的逻辑 setup_models(), 新建 env,并且枚举 env 里面加载的 ModelClass, 将 ModelClass 实例化为 recordset, 此时的 recoredset 是空的,称之为 model
setup_models() 过程中,会对 model 进行一系列的操作,比如 _prepare_setup(), _setup_base(),_setup_fields(),_setup_complete()
Env
odoo.api.Environment(cr, uid, context={})
新建env,先检查registry是否存在,如果不存在,则建立registry
枚举 env 时,会registry 获取 modelClass 并返回它们的实例,也就是我们常用的
env['res.partner'] 是从注册表 基于 ModelClass 名称获取它的 recordset.
Cursor
env.cr 里面 保存了游标, 可以用 游标执行 SQL
ORM 会将业务操作转换为 SQL 并使用 execute() 在 数据库执行
可以使用 commit() 显式的提交事务, 也可以 使用 cr 的上下文管理器 自动进行自动提交
典型的自动提交的对象
WebRequest
registry.signal_changes()
使用上下文管理器调用 LazyCursor ,也会自动提交
备注:
env[] 是 registry.models 的快捷方式
registry._db 是连接到当前数据库的 连接 odoo.sql_db.Connection
model.pool 等同于 registry
在 Odoo backend 可以使用 self.env 获取 env, 或者 self.registry self.pool 获取 registry
在 Odoo frontend 则可以使用 request.env 获取 env, request.registry 获取 registry