宜兴通达竭诚为您服务。

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

2020-10-21 03:10:00     作者: Administrator     来源:互联网,版权归作者所有     浏览次数: 79     文字大小:【】【】【

你没有登录,文章中的图片无法正常显示,请点击登录

前面我们介绍了模型的基本继承,在官方文档中称为经典继承。这是最常用的继承方式,最容易想到的就是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








相关文章 评论

服务原则及地区范围

宜兴通达团队,在企业网络维护和企业信息化建设与咨询方面,有10多年经验。

我团队愿与客户一道,力求彻底解决客户问题!
我们不是在给企业提供“头痛医头、脚痛医脚”的暂时解决方案,而是在部署根本性安全与稳定服务!!
我们愿携手客户,建立企业IT规划;杜绝随意安装系统、软件等操作;力求共同维护有序、安全、稳定的网络办公环境!!!
IT服务,服务是根本,客户是上帝;我们提供快速响应、快速上门、快速排查,提供优质高效的服务!!!!

通达团队提供全国范围内的服务,服务形式包括远程协助、电话咨询、电子邮件咨询、传真咨询、问答平台的问题解决等。

宜兴地区提供上门服务:

  • 市区服务:宜城街道、城北街道(屺亭街道)、新街街道、新庄街道、环科园、渚桥开发区
  • 市郊服务:张渚镇、西渚镇、太华镇、徐舍镇、官林镇、杨巷镇、新建镇、和桥镇、高塍镇、万石镇、周铁镇、芳桥镇、丁蜀镇、湖父镇。
  • 联系电话:189-21-343434
  • 在线沟通: