- 在被继承模块的同级文件夹中创建继承模块的文件夹
- 创建
__init__.py
和__manifest__.py
__manifest__.py
中depends属性中加上被继承的模块名'depends': ['module_name'],
in-place继承
in-place继承实际上就是对已有模型的引用并在原处做修改。
- 在py文件里定义类,使用
_inherit
属性即可,_inherit = 'module_name'
。 - 这种继承会获得原有模型的所有属性,如果想更改已有字段、属性甚至方法,直接在此模型里重写即可,如果想添加新的字段、属性和方法,直接在此模型写即可。
- 这种继承中所做的所有更改都会作用在原有模型上。
视图和数据的继承
视图的继承与修改
- 添加
inherit_id
属性,inherit_id
记录字段通过ref
属性指向继承视图的外部标识符,<field name="inherit_id" ref="module_name.view_name" />
,ref
可以将指定视图的外部标识符转换成数据库里的id。 - 定位节点的方法有三种,官方文档是这样讲的:
There are three types of element locators for matching a target
element:
- An
xpath
element with anexpr
attribute.expr
is an XPath expression applied to the currentarch
, the first node it finds is the match- a
field
element with aname
attribute, matches the firstfield
with thesamename
. All other attributes are ignored during matching- any other element: the first element with the same name and identical attributes(ignoring
position
andversion
attributes) is matched
(1) 最简单的方法就是第二种——使用唯一标识属性,也就是field
中的name
字段。
在arch里定义:
<field name="name" position="after">
<!-- 此处添加修改内容 -->
</field>
其中position
用来指定要执行的继承操作:
The inheritance spec may have an optional position attribute
specifying how the matched node should be altered:
inside
(default)
the content of the inheritance spec is appended to the matched node
replace
the content of the inheritance spec replaces the matched node. Any text node containing only$0
within the contents of the spec will be replaced by a complete copy of the matched node, effectively wrapping the matched node.
after
the content of the inheritance spec is added to the matched node’s parent, after the matched node
before
the content of the inheritance spec is added to the matched node’s parent, before the matched node
attributes
the content of the inheritance spec should beattribute
elements with a
name
attribute and an optional body:
(1) if theattribute
element has a body, a new attributed named after itsname
is created on the matched node with theattribute
element’s text as value
if theattribute
element has no body, the attribute named
after itsname
is removed from the matched node. If no such attribute
exists, an error is raised
Additionally, theposition
move
can be used as a direct child of a spec with ainside
,replace
,after
orbefore
position
attribute to move a node.
即:
<xpath expr="//@target" position="after">
<xpath expr="//@node" position="move"/>
</xpath>
<field name="target_field" position="after">
<field name="my_field" position="move"/>
</field>
(2)更高级的方法定位带扩展XML元素——XPath表达式
XPath的语法可以在这里查到:
https://docs.python.org/3/library/xml.etree.elementtree.html#supported-xpath-syntax
修改数据
修改数据直接使用<record id=”<module>.<identifier>” model=”module.name”>
即可,id若存在就会被更新,否则会被创建。
注意,对
<record>
元素进行更新时,就像in-place继承一样,会保留之前的没被重写的数据,但是对像<menuitem>
和<act_window>
这种shortcut
元素,它们需要提供所有的属性,漏写任何一个都会将对应字段置为空值。但可使用<record>
为原本通过shortcut
元素创建的字段设置值。
其他继承机制
原型(prototype)继承
原型继承就是在使用_inherit
属性的同时还使用了与父模型不同的_name
属性,此时会复用所继承并创建一个新的模型,并带有自己的数据表和数据。也就是说把原来的模型拷贝过来再用和改,跟原来模型没关系了就,不过这样很明显会造成数据的冗余,所以一般采用代理继承。
代理(delegation)继承
代理继承相当于使用数据库的外键了,这样不会造成数据的冗余,而且也不容易出现数据不一致的情况,但是继承的模块必须依赖于被继承的模块才能存在。
用法:
- 定义时使用Many2one、One2many、Many2many字段与被继承模型关联,使用
delegate=True
来定义代理继承。
注意:使用代理继承时,原模型的方法并不能被继承。
使用mixin类集成模型
minin实质上就是提供功能给别的模型用,就是轮子。
用法:
- 在
__manifest__.py
文件中添加对mail
的依赖。
'depends': ['library_app', 'mail'],
- 在模型中添加
_inherit
属性,现在模型就会包含这些mixin
的所有字段和方法。
_inherit = ['module.name', 'module2.name']
3.现在就可以在xml
文件里添加相关字段了。
继承Python方法
这跟python继承方法差不多,使用super()
进行上一级方法的调用。
继承Web控制器和模板
web控制器直接import
导入,用Python方法继承,再用super()
调用进行即可。
继承 QWeb 模板和视图的继承是一样的。