微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Odoo如何管理模块数据

版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。

odoo作为世界排名第一的开源ERP系统,经过十几年发展,目前全世界odoo的使用者超过两百万人。odoo的底层结构强大,系统功能繁多,如销售,财务,库存等等,那么这些模块到底是如何进行数据管理,才能保证各个模块功能正常,数据正确而不错乱啦?接下来就让我们一起来看看吧。本节我们将一起学习如何在安装时添加可提供数据的插件模块。

技术准备

运行正常的odoo平台,具体环境搭建各位小伙伴可以自行搜索,这里就不过多赘述了。。。

使用CSV文件加载数据

首先我们一起来看看使用CSV文件加载数据,它的优势在于它是使用标准导出函数导出的数据格式。

准备工作

两个简单的基础模型

如何实现

在__manifest__.py中的data里添加security/ir.model.access.csv:

然后添加权限,

id:权限id,认规则是access_模块名_类名

name:权限名,认规则是模块名.类名

model_id:id:固定写法,规则是model_模块名_类名,其他地方引用权限会用这个id

group_id:id:组id,这里的base.group_user是系统内置组,即员工.员工组,创建账户时,认属于这个组。所以给这个组赋权限,相当于给新账户的认权限

perm_read:读权限(1是有权限,0是无权限)

perm_write:写权限(1是有权限,0是无权限)

perm_create增加权限(1是有权限,0是无权限)

perm_unlink删除权限(1是有权限,0是无权限)

运行原理

仅需将所有数据文件放到声明文件的数据列表中。odoo会通过文件扩展名来确定其文件类型。CSV文件一个特别之处在于它必须匹配所导入的模型名称,本例中,该模型为 ir.model.access。第一行应为精确匹配模型字段名称的列名的头部。在通过CSV文件编写many2one字段时,odoo首先尝试将字段值解释为XML ID。如无点号,odoo会将当前模块名添加为命名空间,并在 ir.model.data中查找结果。如若失败,会使用字段值来作为参数调用模型的name_search函数获取第一条返回的结果。如依然失败,该行被视为无效,odoo抛出错误

扩展知识

也可通过CSV文件来导入one2many和many2many字段,但会有些麻烦。通常,最好是分别创建记录然后在XML文件中设置关联,或者通过另一个CSV文件来设置关联。

如果确需在同一个文件中创建关联记录,对数据列进行排序来让标量字段居左、关联模型字段居右,列头包含待关联字段名及所关联的模型字段,由冒号分隔:

上述例子中创建一个名为my group的组,可以通过在组记录的右侧添加列来写入更多的字段。如果需要关联多条记录,重复该行并修改右侧列为对应值。因odoo会为空列填写前一行的值,所以无需拷贝所有数据,添加一行时,对想要填充值的关联模型字段以外的字段只需使用空值。

使用XML文件加载数据

上述中,我们已经学会了如何使用CSV文件加载数据,接下来,我们会通过XML文件添加另一种类型的数据。我们添加一条书和作者的演示数据。还会添加在模块中添加出版社作为常规数据。

如何实现

按照如下步骤创建两个XML文件并在__manifest__.py文件中进行关联。

在你的声明文件中的demo版块中添加一个名为 data/demo.xml的文件

在该文件添加如下内容

在声明文件的data版块中添加一个名为data/data.xml 的文件

在data/data.xml 文件中加入如下 XML 内容

此时如果更新模块,可以看到我们添加的书的记录,点击进去就可以看到作者名和出版社

运行原理

XML数据文件使用<record>标签来创建数据表中一行。<record>标签有两个必填属性:id和model。对于 id 属性,即为外部ID,可以通过ref函数调用,model属性引用模型的_name属性。然后,使用<field>元素来填入数据库中列,这在你所命名的模型中定义。模型还决定哪些字段是必填的并且定义了认值。在这种情况下,无需显式地给这些字段赋值。

有两种方式在模块的声明文件注册XML文件。一种是通过data键,另一种是通过demo键。data键中的数据文件在每次安装或更新模块时进行加载。而demo键中的XML文件仅在对数据库启用了演示数据时才会加载。

第1步中,我们使用了demo键在声明文件注册了XML数据文件。因为使用的是demo键,XML文件仅在对数据库启用了演示数据时才会加载。

在第2步中,<field>元素可以在为标量值时可包含简单文本值。如果需要传递一个文件内容(例如设置图片时),使用<field>元素的file属性并传递相对插件路径的文件名。

设置引用有两种方式。最简单的一种是使用ref属性,可用于many2one字段,仅需包含所要引用记录的XML ID。对于one2many和many2many字段,我们需要使用eval属性。这是一种通用目的属性,可用于运行Python代码来作为字段值使用,例如使用strftime(‘%Y-01-01’)来填充date字段。one2many和many2many中应使用三个元素元组列表,元组的第一个值决定所要采取的操作。在eval属性内,我们可以访问一个名为ref的函数,它返回以字符串传入的XML ID 对应的数据库ID。这让我们不需要知道在不同的数据库中原始ID是否不同,也可直接引用记录,如下所示:

(2, id, False):它会删除通过数据库 id 所关联的记录。元组的第三个元素被忽略。

(3, id, False):它通过id取消记录的one2many字段关联。注意这个操作不会删除原记录,已有记录保持原样。元组的最后一个元素也被忽略。

(4, id, False):它添加一个已有记录 id的关联,元组的最一个元素被忽略。这应该是最常使用到的,通常伴有ref函数来通过其XML ID来获取记录的数据库 ID。

(5, False, False):它会切断所有关联,但仍保持所关联的记录的完整性。

(6, False, [id, …]):它会清除当前引用的记录来将它们替换为 ID 列表中包含的记录。元组的第二个元素被忽略。

第3和第4步同前两步,只是使用data键来取代了demo键。这表示每次安装或升级模块时都会加载这些XML文件

重要:注意数据文件中的顺序很重要,并且数据文件中的记录仅能引用该文件之前列表中数据文件所定义的记录。这也是为什么需要保持查看模块是否在空数据库中安装,因为在开发过程中,会经常在各处添加记录,能够使用的前提是后续所定义记录通过前几次更新已存在于数据库中。

扩展知识

字段元素还可以包含function元素,它调用模型中的方法来提供字段值。参见在XML文件调用函数一节,其中我们仅通过调用函数来在应用中直接绕过加载机制并写入数据库

前述列表中没有包含0和1,因为在载入数据时这两者并没有什么用处。为保持完整性,说明如下:

(0, False, {‘key’: value}):它会新建所引用模型的记录,字段值由第3个位置参数的字典填写。元组的第二个元素被忽略。因为这些记录不包含XML ID并在每次更新模块时运行,会导致重复数据,最好避免使用。

(1, id, {‘key’: value}):它可用于写入已关联的记录。由于上述的同样原因,应避免在XML文件中使用这种语法。

在XML文件调用函数

可以通过XML文件创建各种类型的记录,但有时生成包含一些业务逻辑的数据会很困难。我们可能会希望用户在生产环境中安装依赖模块时修改记录。例如,假设你想要创建一个模块来在线展示书籍。my_library模块已有图片封面字段。设想在新的模块中你实现了缩减图像大小以及在新的缩略图字段中存储它的逻辑。现在在用户安装这一模块时,可能已有图书和图像了。不太可能在XML文件中通过<record>标签生成缩略图在这种情况下,可以通过<function>标签调用模型方法

如何实现

按照如下步骤通过XML文件调用Python方法

首先在模型中添加更新数据价格的方法

在数据XML文件添加<function>:

运行原理

在第一步中,我们添加了_update_book_price()方法,它搜索所有图书并将它们的价格增加10 。我们在方法名前加上下划线_,是因为它被ORM视作私有,不允许通过RPC调用

在第二步中,我们使用了<function>标签添加了两个属性

model:在其中声明方法的模型名称

name:想要调用方法

在安装这一模块时,_update_book_price()会被调用并且书籍的价格会被加上10。

扩展知识

通过<function>可以向函数发送参数。假设只想要在某个分类增加图书的价格并且通过参数发送这一增加的值。

那么,需要创建一个方法来接收分类作为参数,如下:

传递分类和数值作为参数,需要使用eval属性,如下:

在安装这一模块时,会对指定分类的图书单价增加20。

从XML文件删除记录

在前面的学习中,我们学习了如何通过XML文件创建或更新记录。但有时对依赖的模块,会希望要删除此前创建的记录。这可以通过<delete>标签实现。

准备工作

首先,我们将通过XML文件添加一些分类,然后删除它们。在真实场景中,会从另一个模块中创建这一记录。但为进行简化,我们将在相同的 XML 文件添加一些分类,如下:

如何实现

有两种方式从XML文件删除记录:

通过此前创建记录的 XML ID:

通过搜索域:

运行原理

如果你使用<delete>标签要从模型中删除记录,需要在model属性中提供模型的名称。这是一个必填的属性

在第一个方法中,需要提供此前从另一个模块数据文件中创建记录的XML ID。在模块的安装过程中,odoo会尝试查找该记录。如果以给定XML ID查找到了记录,会删除该记录,否则会抛出一个错误。可以仅删除通过XML文件创建的记录(或带有XML ID的记录)。

在第二个方法中,需要在domain属性中传递作用域。在模块的安装过程中,odoo会通过该域搜索记录。如果查找到记录,则进行删除。如果给定域没有匹配到任何记录的话该选项不会抛出异常。使用该选项时要极其小心,因为搜索选项会删除所有匹配域的记录,而导致它会删除用户的数据。

警告:odoo很少使用<delete>,因为它很危险。如果使用不慎,可能会导致系统崩溃。尽可能避免使用它

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。