转载请注明原文地址:http://www.javashuo.com/article/p-eosipssa-kz.htmlhtml
一:继承数据库
在不改变底层对象的时候添加新的功能——这是经过继承机制来实现的,做为在现有对象之上的修改层,这些修改能够发生在全部级别:模型,视图和业务逻辑。不是直接修改现有模块,而是建立一个新模块以添加预期的修改。api
1:扩展模型安全
Odoo 模型存在 Python 的模块以外, 在中间注册表那里。对于这个注册表,能够经过模型的方法使用self.env[<model name>]进入。 例如, 经过res.partner 模型获取对象的引用, 代码书写以下 self.env['res.partner']。数据结构
添加字段:dom
# -*- coding: utf-8 -*- from odoo import models, fields, api class Sub(models.Model): _inherit = 'Root' //经过_inherit属性来继承父模型 newCol=fields.XX.... //在下面添加新字段便可。
修改现有字段:ide
为了改变现有字段的属性,只需再次定义该字段,须要修改的属性显式重写便可,会保留未修改的全部其余未在此处明确使用的字段的属性。函数
添加方法:学习
添加新方法很简单:只需在继承类中声明新的函数。测试
修改方法:
扩展或更改现有逻辑,能够经过声明具备彻底相同名称的方法来覆盖相应的方法。
新方法将替换前一个方法,它能够只是扩展继承类的代码,使用Python的super()方法来调用父方法。而后,能够在调用super()方法以前和以后,在原有逻辑周围添加新逻辑。
扩展模型的几种方式:
1)类继承:扩展类中没有_name属性,由于它继承了父类的_name。对现有模型的扩展, 添加新功能,都将添加到现有模型中,不会建立新模型。 所以,在odoo中,根据_name惟一肯定这个模型时找到的就是扩展后的类。(如上面添加字段是类继承)
2)原型继承:咱们想使用具备不一样于父模型的值的_name属性,咱们将得到一个新模型重用来自继承的特性,可是具备本身的数据库表和数据。其实就是把继承的类的功能特性拷贝衣服给新的模型使用,并不改变被继承模型。
复制意味着被继承的方法和字段也将在继承模型中可用。 对于字段,这意味着它们也将被建立并存储在目标模型的数据库表中。 原始(继承)和新(继承)模型的数据记录保持不相关。 只有定义是共享的。
3)代理继承(委托继承):使用_inherits属性,它容许一个模型以透明的方式包含其余模型。经过字典映射继承模型与字段的关系,并关联它们。(至关于成员变量:引用一个外部的类对象赋值给这个模型的一个成员,可是对象的值是保存在被引用的类的数据库表中的。可是在当前类经过成员修改了变量值的,则会同步到被引用的类的数据库表中)
优势是不须要在几个表之间重复数据结构,例如地址。 任何须要包含地址的新模型均可以将其委派给嵌入式合做伙伴模型。 若是在合做伙伴地址字段中引入了修改,则这些修改会当即提供给嵌入它的全部模型!
2:扩展视图
表单,列表和搜索视图是使用arch XML结构定义的。 要扩展视图,咱们须要一种方法来修改这个XML。 这意味着须要定位XML中的元素位置,而后在这些位置引入修改。
对于XML,在其中定位元素的最好方法是使用XPath表达式。若是XPath表达式匹配到多个元素,只有第一个元素会被修改。 所以,表达式应该使用独特的属性以使其指定尽量具体。 使用name属性是确保咱们找到扩展点的确切xml元素的最简单方法。 所以,在咱们的视图XML元素上定义name属性是很重要的。
Xpath表达式的格式:expr="//标签名[@属性]='属性值'":找到属性=属性值的标签位置。
下面是一个写在arch中的实如今is_done字段以前添加date_deadline字段的具体例子:
<xpath expr="//field[@name]='is_done'" position="before"> //expr属性值的意思是:找到<filed name="is_done"/>的标签 <field name="date_deadline" /> </xpath>
Odoo为此提供了快捷符号,所以大多数时候咱们能够彻底避免XPath语法。 咱们仅使用要定位的元素的特定属性及定位类型相关信息就能够了。
<field name="is_done" position="before"> <field name="date_deadline" /> </field>
若是字段在同一视图中屡次出现,则应始终使用XPath语法。
position属性是可选的:
after:将内容添加到父元素之中,匹配的节点以后。 before:添加内容在匹配节点以前。 inside(默认值):匹配节点内的追加内容。 replace:替换匹配的节点。若是使用空内容,它将删除该匹配的元素。 attributes:修改匹配元素的XML属性。在元素内容使用<attribute name =“attr-name”>实现给属性name设置新属性值attr-name。
1)扩展表单视图
<record id="view_form_模块名_inherited" model="ir.ui.view"> <field name="name">模块名_extension</field> <field name="model">模块.数据模型</field> <field name="inherit_id" ref="模块_模型.被继承的form表单name属性"/> <field name="arch" type="xml"> //在arch中进行扩展操做:定位—>插入/修改 <field name="定位标签位置" position="在标签的哪里进行扩展"> <field ......> //扩展内容 </field> </field> </record>
2)扩展列表视图
<record id="view_tree_模型名_inherited" model="ir.ui.view"> <field name="name">模型名 extension</field> <field name="model">模块.模型</field> <field name="inherit_id" ref="被继承的tree视图name名"/> <field name="arch" type="xml">//在arch中进行扩展 <field name="定位标签名" position="扩展位置"> <field ....进行扩展 /> </field> </field> </record>
3)扩展搜索视图
<record id="view_filter_模型名_inherited" model="ir.ui.view"> <field name="name"> extension</field> <field name="model">模型名</field> <field name="inherit_id" ref="被继承的filter视图名"/> <field name="arch" type="xml"> //下面进行定位、扩展举例 <field name="name" position="after"> <filter name="filter_my_tasks" string="My Tasks" domain="[('user_id','in',[uid,False])]" /> </field> </field> </record>
4)修改记录
对于记录:
<record id="x" model="y">
数据记录加载时,实际上对模型y执行了create或update操做︰ 若是记录x不存在,则建立它; 不然,更新原来对应的值。
修改菜单项:
< ! — — 修改菜单项--> <record id="菜单视图id" model="ir.ui.menu"> //进行修改 </record>
修改action_window:
<record model="ir.actions.act_window" id="action菜单id"> //进行修改 </record>
二:模块数据
1:列表数据的导出
数据导出是tree视图的标准功能,不涉及编码。
只需在列表视图左侧复选框勾选须要导出的记录,而后点击列表上方“动做”下拉列表,选择“导出”。
在导出对话框中选择须要导出的列、导出的格式(通常选择CSV,勾选 导入兼容导出),而后点击“导出到文件”便可。
2:导入数据
在面板点击“导入”按钮,选择文件后载入。而后点击“验证”,检查文件内容的格式合法性,若是正常,则点击“导入”便可。
3:模块数据
模块使用数据文件,将其配置加载到数据库,能够经过CSV和XML文件完成。为了完整性,也可使用YAML文件格式,可是它不多用于加载数据。
一个附加的限制是文件名必须与要加载数据的模型的名称匹配,这样系统才能够推断应该将数据导入相应的模型。
数据CSV文件的常见用法是加载到ir.model.access模型中的安全定义。
4:演示数据
一个模块在安装时,尽可能事先定义一些演示数据,方便在安装后进行测试使用。
演示数据咱们放在data目录下,命名为 xx.xx.csv或者xx.xx.xml
而后在manifest文件中的data属性进行配置。
5:XML
noupdate:重复数据加载时,将重写上次运行中加载的记录。 这意味着升级一个模块将覆盖在数据库内可能已经进行的任何手动更改。此从新导入行为是默认值,但能够更改,以便在升级模块时,某些数据文件记录保持不变。 这是经过<odoo>或元素的noupdate =“1”属性完成的。 这些记录将在安装addon模块时建立,但在后续模块升级中不会对其进行任何操做。
XML中定义记录:
每一个<record>元素有两个基本属性id和model,而且包含为每列分配值的<field>元素。如前所述,id属性对应于记录的外部标识符,而且模型属性对应于要写入记录的目标模型。
设置字段值的几种方式以下:
1:<record>元素定义数据记录并包含<field>元素以设置每一个字段的值,field元素的name属性标识要写入的字段,要写入的值是元素内容:字段的开始和结束标记之间的文本。
2:定义字段值的更精细的替代方法是eval属性:它评估一个Python表达式并将结果值分配给字段。
<field name="date_deadline" eval="(datetime.now() + timedelta(-1)).strftime('%Y-%m-%d')" />
3:<field>元素还有一个ref属性,用于使用外部标识符设置many-to-one字段的值。
<field name="user_id" ref="base.user_demo" />
XML中触发函数:
能够经过<function>元素,在其加载过程当中执行方法。这能够用来创建演示和测试数据。
<function model="数据模型" name="数据模型中的方法" eval="参数" />
另外一方式是触发工做流:
<workflow model="模型" ref="工做流实例" action="工做流信号:触发工做流" />