odoo(openerp) - BaseModel的create_instance方法

本文深入解析了Odoo中BaseModel的create_instance方法,包括其在模型对象初始化和继承过程中的作用。该方法用于创建模型实例,处理多继承,并确保属性和方法的正确继承。在多继承时,同名方法和属性以首次出现的父类为准。最后,通过__new__和__init__完成对象创建与初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BaseModel的create_instance方法

注意:以下代码基于odoo四月份的trunk版,新版本中create_instance方法已经被_build_model方法替换,但是原理基本一样。

 

如果没有耐心看原理的,可以直接看结论:

1、  本文主要分析odoo模型对象初始化过程和继承过程。

2、  odoo中对象不是直接创建,而是调用类函数create_instance创建,并且由于在__new__方法中返回的是None,所以即使我们使用小括号创建对象也不会返回新对象。

3、  odoo可以多继承,当”_inherit”字段为列表时,就使用了odoo的对象多继承,如果是字符串,则只有一个父对象,但是并不建议使用多继承

4、  如果使用对象多继承的时候,同名的方法和属性都是以第一个出现的父类中的方法和属性为准,继承后面不会覆盖前面。举个例子,基类BaseModel中的create方法不会被其他父类的create方法覆盖。

 

我们知道,odoo中自己实现的模型都是继承自BaseModel这个基类,同时BaseModel也实现了一系列模型的基本操作,如search、create、write等方法,我们在操作模型的时候可以直接调用父类的相应方法。create_instance就是BaseModel众多方法其中之一,但是这个方法非常特殊。首先这是一个类方法,如下图:



这意味着调用它的是类而不是对象实例。

 

首先该方法会判断对象是否有父类,即_inherit字段是否存在,(注意,里的父类是指odoo层面的父类,而不是python级别的父类),如果有父类,则会遍历所有父类(因为有可能是继承多个父类,如果你_inherit字段是列表类型而不是字符串时,就是多继承),遍历过程都会进行如下操作:

1、记录父类的__class__属性:

 

2、遍历如下列表,并且copy给子类:


遍历如下图所示,先定义一个空字典nattr,对每个属性都从父类中copy一份:


处理遍历时会对”_columns”、”_constraints”进行特殊处理,如果其他属性是字典类型,则直接把原属性更新到new中,如下图所示:


对_columns是在上面那行代码之前进行处理的,因为_columns也是字典类型,相当于对这个字段进行预处理之后再进行常规处理。如果_columns中的字段具有manual属性,则不继承该字段。

如果是列表属性,则直接扩展,但是attributes里面处理_constraints是list类型外其他的都是字典类型,而_constraints已经被特殊处理了,也就是说下面这行代码正常情况下是不会被调用到的。

 

最后生成一个新的type,如下图:


需要注意的是,虽然type的第三个参数dict中的nattr会覆盖同名的属性,但是nattr中的同名属性已经在前面的代码中被子类的同名属性覆盖了一次,所以不会造成影响。


此时这个cls已经具备了该父类的方法定义和属性了。然后不断重复上述动作,直到遍历完所有父类。遍历完所有父类之后,cls就具备了所有父类的方法。

 

需要注意的是由于cls本身是BaseModel,所以,当父类覆写了BaseModel方法的时候,继承对象并不会继承父类的覆写方法,只会继承父类新增的方法,同理,如果两个父类有相同的方法,子类会继承第一个父类的方法(继承方法调用基于先根序)。在我们实际编写模块时需要注意这一点。

当需要创建的对象的类型构建完成之后,程序会调用object的__new__方法创建对象,然后手动调用对象的__init__方法进行初始化操作,如下图:


在__init__方法中会把自己添加到registry中去,所以虽然该方法是由registry的load方法调用,但是对象注册到registry是由对象自身完成的。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值