CSV演示数据
通过demo 属性来声明,后接一个包含模块相对路径的文件名列表。即文件名需与所导入到的模型名称一致
例如res.partner.csv:
id,name
res_partner_alexandre,"Alexandre Fayolle"
res_partner_daniel,"Daniel Reis"
res_partner_holger,"Holger Brunn"
res_partner_packt,"Packt Publishing"
在__manifest__.py的 demo 属性中声明数据文件:
'demo': [
'data/res.partner.csv',
],
文件会以声明的顺序来加载,这个很重要,因为文件的记录无法引用尚未创建的记录。
只要启用了安装演示数据,在下次更新模块时,就会导入文件中的内容。
注:数据文件会在模块升级时重新导入,但演示文件则并非如此,它们仅在安装时导入
使用 XML 数据文件
添加一个数据文件data/book_demo.xml来进行展示,文件内容如下:
<?xml version="1.0"?>
<odoo noupdate="1">
<!-- Data to load -->
<record model="res.partner" id="res_partner_huxley">
<field name="name">Aldous Huxley</field>
</record>
<record model="library.book" id="library_book_bnw">
<field name="name">Brave New World</field>
<field name="author_ids"
eval="[(4, ref('res_partner_huxley'))]" />
<field name="date_published">1932-01-01</field>
</record>
</odoo>
同理,新的数据文件应在__manifest__.py中声明:
"demo": [
"data/res.partner.csv",
"data/book_demo.xml",
],
XML文件包含一个外层<odoo>
顶级元素,内部可包含多个<record>
元素,对应 CSV 的数据行。
<record>
元素有两个强制属性: model 和作为记录外部标识符的 id,每个字段使用一个标签来进行写入。
noupdate 数据属性
noupdate=”0″是默认值,升级模块时,会重新加载数据并重写模块记录。
可以通关设置noupdate=”1″,来让有些数据仅在安装时导入,升级不影响。
在 XML 中定义记录
在 XML 数据文件中,每个 元素有两个基本属性:id 和 model,并包含为对应列设置值的元素。 id 属性对应记录外部标识符,model 对应目标模型。元素有几种赋值的方法,下面一起来看看。
-
直接为字段设置值
元素的 name 属性标识要写入的字段。写入的值是元素内容:字段开、闭标签之间的文本。
对于日期和日期,可使用带返回 date 或 datetime 对象表达式的 eval 属性设置。返回的“YYYY-mm-dd”和“YYYY-mm-dd HH:MM:SS”字符串会进行对应转化。
对于布尔字段,“0” 和“False”都会转换成 False,而任意非空值都会转换成 True。 -
通过表达式设置值
设置字段值更复杂的方式是通过 eval 属性。它会运行 Python 表达式并将结果赋值给字段。
比如,把值设为前一天,可使用如下代码:<field name="date_published" eval="(datetime.now() + timedelta(-1))" />
求值上下文还可使用ref()函数,用于将外部标识符转换为对应的数据库 ID。这可用于为关联字段设置值。比如,可以使用它为publisher_id设置值:
<field name="publisher_id" eval="ref('res_partner_packt')" />
-
在多对一关联字段上设置值
简单的替代方式是在元素中使用的ref 属性,例如:<field name="publisher_id" ref="res_partner_packt" />
上例为publisher_id多对一字段设置值,引用XML ID为res_partner_packt的数据库记录。
-
在对多关联字段上设置值
对于一对多和多对多字段,设置的不是单个 ID,而是一组关联 ID。并且还进行几种操作:我们可能需要将当前的关联记录列表替换成另外一个,或为其添加几条记录,甚至是删除其中的一些记录。要让对多字段支持写操作,我们要在 eval 属性中使用一种特殊的语法。我们使用三元元组列表来写入对多字段。每个元组有三个元素,构成一条写入命令,根据第一个元素中的代码进行对应操作。
重写图书作者列表,会使用如下代码:<field name = "author_ids" eval = "[(6, 0, [ref('res_partner_alexandre'),ref('res_partner_holger')] )]"/>
往当前图书作者列表追加关联记录,需要添加如下代码:
<field name="author_ids" eval="[(4, ref('res_partner_daniel'))]"/>
完整的*对多写入命令如下:
(0, _ , {‘field’: value})新建一条记录并将其与之关联
(1, id, {‘field’: value})更新已关联记录的值
(2, id, _)移除关联并删除 id 关联的记录
(3, id, _)移除关联但不删除 id 关联的记录。通常使用它来删除多对多字段的关联记录
(4, id, _)关联已存在记录,仅适用于多对多字段
(5, _, _)删除所有关联,但不删除关联记录
(6, _, [ids])替换已关联记录列表为此处的列表
上述下划线_字符代表非相关值,通常填入 0 或 False。
注:后面的非关联值可以放心地省略掉,如(4, id, _) 可使用(4, id)
XML 文件中的其它操作
删除记录
我们可以使用元素删除数据记录,使用 ID 或搜索作用域来定位要删除的记录。
例如,使用搜索作用域查找记录并删除:
<delete model="res.partner" search="[('id','=',ref('library_app.res_partner_daniel'))]"/>
如果知道要删除记录的具体 ID,也可使用 id 属性。上例正是这样,还可以写成这样:
<delete model="res.partner" id="library_app.res_partner_daniel" />
调用模型方法
XML 文件还可以通过元素在加载过程中执行任意方法。这可用于设定演示和测试数据。
比如 Odoo 捆绑的 Notes 应用,使用它来设定演示数据:
<data noupdate="1">
<function model="res.users" name="_init_data_user_note_stages" eval="[]"/>
</data>
这会调用res.users模型中的_init_data_user_note_stages方法,不传任何参数。参数列表通过eval属性传递,此处为空列表
XML 的简单样例
<odoo noupdate="1">
<data>
<record id="object0" model="test_demo.test_demo">
<field name="name">Object 0</field>
<field name="value">0</field>
<field name="iebs" ref="test_demo.iebs1" />
</record>
<record id="object1" model="test_demo.test_demo">
<field name="name">Object 1</field>
<field name="value">10</field>
</record>
<record id="object2" model="test_demo.test_demo">
<field name="name">Object 2</field>
<field name="value">20</field>
</record>
</data>
</odoo>
demo数据只在勾选演示数据后才会加载(only loaded in demonstration mode),只存放演示数据
data数据在系统启动后会自动进行加载(always loaded),可存放演示数据和实际数据
ref="模块名.record 的id”,一般是iebs是Many2one的时候用。