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

前面我们介绍了模型的基本继承,在官方文档中称为经典继承。这是最常用的继承方式,最容易想到的就是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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

r_nznf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值