赞
踩
继承机制是Odoo一个非常重要的功能,继承其他模块中定义的功能使我们可以无需修改底层对象就可以为我们的模块添加新的功能。比如添加字段或方法,修改已有字段或继承已有方法来执行新的逻辑。根据官方文档,Odoo提供三种类型的继承,分别是:
类继承(扩展),可用于对已有模型添加新字段或方法。
class ResPartner(models.Model):
_inherit = 'res.partner'
authored_book_ids = fields.Many2many('library.book', string='著作',)
count_books = fields.Integer('著书数量', compute='_compute_count_books')
class ResPartner(models.Model):
# ...
@api.depends('authored_book_ids')
def _compute_count_books(self):
for r in self:
r.count_books = len(r.authored_book_ids)
通过_inherit实现类继承,也可以将父级模型的功能copy到一个全新的模型中,通过添加一个带有不同标识符的_name属性来实现。
示例:
class LibraryMember(models.Model):
_inherit = 'res.partner'
_name = 'library.member'
这种做法中,新模型有自己的数据表,包含完全独立于res.partner原有模型的自身数据。因其仍继承Partner模型,此后的任意修改也会影响到新模型。在官方文档中,这被称为原型继承,但在实践中很少使用,原因在于代理继承通常可以更高效的方式满足这一需求,也无需复制数据结构。
原型继承,用于从已有模型中copy整个定义。
比如生成对 student 模型的拷贝,操作步骤依次为:
(1)在 models/ 目录下新建一个 student_copy.py 文件。
(2)在 student_copy.py 文件中添加如下代码:
from odoo import models, fields, api
class StudentCopy(models.Model):
_name = 'student.copy'
_inherit = 'student'
_description = "Student's Copy"
(3)在models/init.py 文件中导入一条新的文件引用。
from . import student_copy
有时我们希望在不修改原有模型的基础上,根据原有模型创建一个新模型来使用原有功能。这时可以通过原型继承来copy原有模型,但这会导致重复的数据结构。如果希望在不复制数据结构的前提下copy原有模型,就需要用到Odoo的代理继承。
要在图书馆用户中添加会员,会员需要保留普通用户的所有数据,同时也要新增一些会员信息,比如:起始日期、结束日期、会员卡号。向原有模型中添加这些新字段或许可行,但是普通用户不需要这些信息,这时候就可以用代理继承。
(1)添加新模型来继承原有模型:
class LibraryMember(models.Model):
_name = 'library.member'
_inherits = {'res.partner': 'partner_id'}
partner_id = fields.Many2one('res.partner',ondelete='cascade')
(2)添加针对会员的字段:
# class LibraryMember(models.Model):
# ...
date_start = fields.Date('起始日期')
date_end = fields.Date('结束日期')
member_number = fields.Char()
代理继承使用的不是 _inherit,而是 _inherits 类属性。_inherits模型属性设置我们想要继承的父级模型。本例中只有一个 res.partner 模型。它的值是一个键值对字典,键是被继承的模型,而值是用于关联它们的字段名。本例中,partner_id 是用于关联父级模型Partner的字段。
支持多态继承,可以从两个或多个其它的模型中进行继承。
注意:代理继承仅用于字段,而不能用于方法。因此,如果原有模型有一个 do_something() 方法,新模型不会自动继承它。
新建会员时,数据库会发生什么?
删除是会员的成员时会发生什么?
可通过关联字段的ondelete值来决定。对 partner_id 这里使用了cascade,表示删除成员会同时删除对应的会员。
继承代理有一个快捷方式,代替创建一个 _inherits 字典,可以在 Many2one 字段定义中使用 delegate=True 属性。这和 _inherits 选项的功能完全一样,其主要优点是更为简洁。
示例:
class LibraryMember(models.Model):
_name = 'library.member'
partner_id = fields.Many2one('res.partner', ondelete='cascade', delegate=True)
date_start = fields.Date('起始日期')
date_end = fields.Date('结束日期')
member_number = fields.Char()
在模块定制过程中,有许多情况需要继承一些模型以实现特定的情况。下图简要总结了上文中三种继承类型的区别与联系:
转载自:https://zhuanlan.zhihu.com/p/395341464
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。