ODOO12图书项目其它模型继承机制

it2024-09-27  43

前面我们介绍了模型的基本继承,在官方文档中称为经典继承。这是最常用的继承方式,最容易想到的就是in-place继承。获取模型并对其继承。添加的新功能会自动添加到已有模型中,而不会创建新模型。 可以为_inherit 属性传入多个值来继承多个父模型。大多数情况下这通过 mixin 类完成,mixin类是实现可复用的通用功能。也可以像普通模型那样独立使用,像是一个功能容器,可随时加到其它模型中。 如在使用_inherit 属性的同时还使用了与父模型不同的_name属性,此时会复用所继承并创建一个新的模型,并带有自己的数据表和数据。官方文档称其为原型(prototype)继承。下面我们会拿一个模型,并为其创建一个拷贝。在添加新功能时,只会被加到新模型中,而不会变更原模型。 此外还有代理(delegation)继承,通过_inherits 属性来使用(注意最后有一个 s)。这允许我们创建一个包含和继承已有模型的新模型。新模型创建新记录时,在原模型中也会被创建并使用many-to-one 字段关联。查看新模型的人可以看到所有原模型和新模型中的字段,但在后台两个模型分别处理各自的数据。 下面我们一起来了解详情。 使用原型继承拷贝功能 前文我们继承模型时使用了_inherit 属性,创建一个类继承library.book 并添加了一些功能。类中没有使用_name属性,不指明即使用library.book。如果设置了不个不同值的_name 属性,会通过从所继承的模型拷贝功能创建新模型。 在实际开发中,这类继承一般通过抽象 mixin 类,很少这样直接继承普通模型,因为这样会创建冗余的数据结构。Odoo 还有一种代理继承机制可避免这类数据结构冗余,所以普通模型通常会使用这种方法来做继承。 使用代理继承内嵌模型 使用代理继承无需复制数据即可在数据库中复用数据结构,这通过将一个模型嵌入另一个来实现。UML 中这种称作组合(composition)关系:父类无需子类即可存在,而子类必须要有父类才能存在。 比如,对于内核 User模型,每条记录包含一条 Partner 记录,因此包含 Partner 中的所有字段以及User自身的一些字段。 在图书项目中,我们要添加一个图书会员模型。会员有会员卡并通过会员卡借阅读书。我们要记录卡号,还要存储email 和地址这类个人信息。Partner 模型已包含联系和地址信息,所以最好是进行复用,而不去创建重复的数据结构。 为会员模型创建library_member/models/library_member.py文件并加入如下代码:

from odoo import fields, models class Member(models.Model): _name = 'library.member' _description = 'Library Member' card_number = fields.Char() partner_id = fields.Many2one( 'res.partner', delegate=True, ondelete='cascade', required=True)

使用代理继承,library.member 中嵌入了继承模型res.partner,因此在创建会员记录时,一个关联的 Partner 会自动被创建并通过partner_id字段引用。 透过代理机制,嵌套模型的所有字段就像父模型字段一样自动可用。本例中,会员卡模型可使用 Partner 中的所有字段,如 name, address和 email,以及会员自身的独有字段,如card_number。在后台中,Partner 字段存储在关联的 Partner 记录,没有重复的数据结构。 与原型继承相比,代理继承的好处在于无需跨表重复像地址这样的数据。任何需包含地址的新模型通过代理嵌入了 Partner 模型。如果在 Partner 中修改 address字段,在所有嵌入的模型中可以马上使用。 不要忘记在library_member/model/init.py文件中加入:

from . import library_book from . import library_member

要使用我们创建的 Member 模型,还要完成以下步骤:

添加安全权限控制列表(ACL)添加菜单项添加表单和列表视图更新manifest文件来声明这些新增数据文件

要创建安全ACL,创建library_member/security/ir.model.access.csv文件并加入如下代码:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_member_user,Member User Access,model_library_member,library_app.library_group_user,1,1,1,0 access_member_manager,Member Manager Access,model_library_member,library_app.library_group_manager,1,1,1,1

要添加菜单项,创建library_member/views/library_menu.xml文件并加入如下代码:

<?xml version="1.0"?> <odoo> <act_window id="action_library_member" name="Library Members" res_model="library.member" view_mode="tree,form" /> <menuitem id="menu_library_member" name="Members" action="action_library_member" parent="library_app.menu_library" /> </odoo>

要添加视图,创建library_member/views/member_view.xml文件并加入如下代码:

<?xml version="1.0"?> <odoo> <record id="view_form_member" model="ir.ui.view"> <field name="name">Library Member Form View</field> <field name="model">library.member</field> <field name="arch" type="xml"> <form> <group> <field name="name" /> <field name="email" /> <field name="card_number" /> </group> </form> </field> </record> <record id="view_tree_member" model="ir.ui.view"> <field name="name">Library Member List View</field> <field name="model">library.member</field> <field name="arch" type="xml"> <tree> <field name="name" /> <field name="card_number" /> </tree> </field> </record> </odoo>

最后,编辑manifest文件来声明这三个新文件:

'data': [ 'views/book_view.xml', 'security/library_security.xml', 'security/ir.model.access.csv', 'views/member_view.xml', 'views/library_menu.xml', ],

如果编写正确,在进行模型更新后即可使用新的图书会员模型了。 使用 mixin类继承模型 原型继承主要用于支持 mixin 类。mixin 是基于 models.Abstract 的抽象的模型(而不是models.Model),它在数据库中没有实际的体现,而是提供功能供其它模型复用(混合 mixed in)。Odoo 插件提供多种 mixin,最常的两种由 Discuss 应用(mail 模块)提供:

mail.thread提供在许多文档表单下方或右侧的消息面板功能,以及消息和通知相关逻辑。这在我们自己的模型中将经常会添加,下面就来一起学习下。mail.activity.mixin模型提供待办任务计划。

我们一起来为 Member 模型添加上述两种 mixin。社交消息功能由 mail 模块的mail.thread模型提供,要将其加入自定义模型,应进行如下操作:

1.通过 mixin 模型 mail 为插件模块添加依赖 2.让类继承mail.thread和mail.activity.mixin两个 mixin 类 3.将message_follower_ids, message_ids和activity_id这些 mixin 的数据字段添加到表单视图

对于第一步扩展模型需要在__manifest__.py文件中添加对 mail 的依赖。

'depends': ['library_app', 'mail'],

第二步中对 mixin 类的继承通过_inherit属性完成,应编辑library_member/models/library_member.py并添加如下代码:

class Member(models.Model): _name = 'library.member' _description = 'Library Member' _inherit = ['mail.thread', 'mail.activity.mixin']

通过添加额外的这行代码,我们的模型就会包含这些 mixin 的所有字段和方法。 第三步中向表单视图添加相关字段,编辑library_member/views/member_view.xml文件并在表单最后添加如下代码:

<record id="view_form_member" model="ir.ui.view"> <field name="name">Library Member Form View</field> <field name="model">library.member</field> <field name="arch" type="xml"> <form> <group> <field name="name" /> <field name="email" /> <field name="card_number" /> </group> <!-- mail mixin fields --> <div class="oe_chatter"> <field name="message_follower_ids" widget="mail_followers"/> <field name="activity_ids" widget="mail_activity"/> <field name="message_ids" widget="mail_thread"/> </div> </form> </field> </record>

mail 模块还为这些字段提供了一些特定的网页组件,以上代码中已使用到。在升级模块后会员表单将变成这样: 有时普通用户仅能访问正在 follow 的记录。在这些情况下我们应添加访问记录规则来让用户可以看到 follow 的记录。本例中用不到这一功能,但可通过[(‘message_partner_ids’, ‘in’, [user.partner_id.id])]或来进行添加。 相关演示: http://www.tderp.com/download/details/odoo12-862 http://ctdrive.tderp.com/file/13502532-467651796

最新回复(0)