前言

在odoo的ORM创建数据字段的过程中,我们会经常需要定义一些字段用来计算某一些字段只和或其他计算结果。

今天介绍一个很好用的方法compute计算属性,这个方法其实是属于写在odoo fields中的属性,但是因为非常常用,还涉及ORM中的方法所以今天就单独列出来详细讲解它的用法。

如何使用odoo compute属性实现自动计算字段

我们看下面的案例。

class FandxProduct(models.Model):
_name = "fandx.product" name = fields.Char("产品名称")
nums = fields.Integer("数量")
unit_price = fields.Float("产品单位价格")

现在有个需求,这是一个产品表,我们需要计算他的每一个产品的总价格(产品单位价格*数量),这时候就要用到我们的主角compute属性,下面看案例。

class FandxProduct(models.Model):
_name = "fandx.product" name = fields.Char("产品名称")
nums = fields.Integer("数量")
unit_price = fields.Float("产品单位价格")
# 使用_compute_all_price
all_price = fields.Float("产品总价格", compute="_compute_all_price") def _compute_all_price(self):
# self取值默认是multi,所以需要循环拿到每一个record的值
for record in self:
# 计算每一个record的all_price的值进行赋值
record.all_price = record.unit_price * record.nums

在字段中定义属性compute并指向计算方法,在数据创建的时候会自动计算这个字段的数据。

这样我们在XML中使用all_price就可以获取到产品的总价格,但是这里还有一个问题。

数据库中是没有进行持久存储的,那么数据数据量一大,每次渲染页面都要进行计算,这样是非常消耗服务器性能的,所以我们就要将计算的字段给存储起来。

如何存储odoo compute计算字段的值

方法很简单,只需要在定义的field中加上store字段,这样就会把计算到的结果给存储到数据库中。

class FandxProduct(models.Model):
_name = "fandx.product" name = fields.Char("产品名称")
nums = fields.Integer("数量")
unit_price = fields.Float("产品单位价格")
# 使用_compute_all_price
# 在字段中加上store = True实现数据的持久化
all_price = fields.Float("产品总价格", compute="_compute_all_price", store=True) def _compute_all_price(self):
# self取值默认是multi,所以需要循环拿到每一个record的值
for record in self:
# 计算每一个record的all_price的值进行赋值
record.all_price = record.unit_price * record.nums

这样我们在数据库中就有了all_price的字段来记录产品总价格。

但是现在又出现一个问题,计算字段是计算出了我们的结果,但是如果nums改变,或者unit_price改变了,计算字段并不会改变怎么办!

compute配合使用depends监听数据变化

class FandxProduct(models.Model):
_name = "fandx.product" name = fields.Char("产品名称")
nums = fields.Integer("数量")
unit_price = fields.Float("产品单位价格")
# 使用_compute_all_price
# 在字段中加上store = True实现数据的持久化
all_price = fields.Float("产品总价格", compute="_compute_all_price", store=True) # 将nums、unit_price字段进行监听,在数据变动的时候再次执行compute指向的方法进行重新赋值计算。
@api.depends('nums', 'unit_price')
def _compute_all_price(self):
# self取值默认是multi,所以需要循环拿到每一个record的值
for record in self:
# 计算每一个record的all_price的值进行赋值
record.all_price = record.unit_price * record.nums

到这里就基本实现了compute的所有经常使用的方法,下面一般会配合compute一起使用的属性inverse

odoo中逆向计算inverse属性使用详解

上面讲解了compute方法是用来计算对应的数据字段的。

inverse方法其实就是compute的逆向方法,默认情况下xml中对应的compute计算字段是readonly的。

当我们加上inverse逆向计算的时候,那么就可以在XML中输入对应的值,然后系统会走inverse对应的方法。

class FandxProduct(models.Model):
_name = "fandx.product" name = fields.Char("产品名称")
nums = fields.Integer("数量")
unit_price = fields.Float("产品单位价格")
# 使用_compute_all_price
# 在字段中加上store = True实现数据的持久化
all_price = fields.Float("产品总价格", compute="_compute_all_price", inverse='_set_unit_price', store=True) # 将nums、unit_price字段进行监听,在数据变动的时候再次执行compute指向的方法进行重新赋值计算。
@api.depends('nums', 'unit_price')
def _compute_all_price(self):
# self取值默认是multi,所以需要循环拿到每一个record的值
for record in self:
# 计算每一个record的all_price的值进行赋值
record.all_price = record.unit_price * record.nums def _set_unit_price(self):
for record in self:
if not all([record.nums, record.all_price]):
continue # 当我们手动修改all_price的值的时候,我们就可以逆向去计算出unit_price的值,进行重新赋值。
record.unit_price = record.all_price / record.nums

总结

  1. odoo的compute可以实现我们对数据字段自动计算的需求。
  2. fields中加入store属性可以实现数据的持久化存储。
  3. compute计算字段在持久化存储之后不会在自动计算,需要我们配合depends来监听指定计算字段在数据改动的时候重新计算数据字段。
  4. inverse方法可以帮助我们解决compute计算字段readonly的问题,并在输入对应的字段进行逆向计算之前的字段。
  5. compute字段默认是store为False的所有search是无效的,还可以指定search的方式实现搜索。这里就不去细讲了,很简单也不常用。
  6. 还有compute_sudo属性可以设置字段在使用的时候是否以超级管理员的方式来进行计算,这里store=True的时候默认为True,否则默认为False,了解一下就可以了。
  7. 如果有问题可以在下方留言。

如何使用odoo的compute方法,自动计算odoo字段的更多相关文章

  1. odoo开发基础--模型之基本字段类型

    定义模型的时候,和python的其他框架类似,可以对比Django,同样是一个模型即:一个class对应生成数据库中的一张表, 只是odoo的继承机制比较复杂一点,在日常的开发中,定义模型的时候, 基 ...

  2. C#中DataTable中的Compute方法使用收集

    原文: C#中DataTable中的Compute方法使用收集 Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详 ...

  3. [datatable]借助DataTable的Compute方法

    借助DataTable的Compute方法,DataTable中数据不用事先排好序. 下面代码中的dt是跟前面的是一样的 DataTable dtName = dt.DefaultView.ToTab ...

  4. C# DataTable Compute方法的使用

    在开发中需要对DataTable的数据进行处理,比如累加,求最大最小及平均值等,以前都采用手工对DataTable进行循环并计算的方式,现在发现DataTable的Compute方法可以轻松实现这些功 ...

  5. 给 odoo 的 bom 明细加上位置字段

    给 odoo 的 bom 明细加上位置字段 odoo 的 BOM 明细没有位置字段,这可无法用于电子生产中. 摸索了几天,找了一些教程,最终实现了. 在模型中找到 mrp_bom_line 增加自定义 ...

  6. c# 基于DataTable的Compute方法的扩展

    DataTable.Compute(String, String) 方法 定义 命名空间:System.Data 程序集:System.Data.dll, netstandard.dll, Syste ...

  7. 转载 C#中DataTable中的Compute方法使用收集

    原文: C#中DataTable中的Compute方法使用收集 Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详 ...

  8. LINQ找出重复和不重复的元素及linq OrderBy 方法 两个字段同时排序有关问题

    //重复元素:3,4,5 //不重复元素:1,8,9 , , , , , , , , , , }; //不重复元素 var unique = arr.GroupBy(i => i) .Where ...

  9. 【转载】Sqlserver使用IsNull方法对空字段进行赋值操作

    在Sqlserver的SQL语句查询过程或者编写存储过程以及自定义函数过程中,有时候字段的值为空,如果为空的字段需要赋值一个默认值,可以使用Sqlserver内置系统函数IsNull来给定一个默认值, ...

随机推荐

  1. C++标准模板库(STL)——vector常见用法详解

    vector的定义 vector<typename> name; 相当于定义了一个一维数组name[SIZE],只不过其长度可以根据需要进行变化,比较节省空间,通俗来讲,vector就是& ...

  2. 用CLion实现本地方法并给java调用

    众所周知,PHP是世界上最好的语言,java排第二,因为PHP无所不能.但是在某些场景下java还要调用本地方法来提高执行的效率,故java只能排第二.java提供了jni(Java Native I ...

  3. 【NX二次开发】调整视图大小

    调整视图大小 tag_t tagView; UF_VIEW_ask_work_view(&tagView); UF_VIEW_fit_view(tagView, 0.7);//if NULL_ ...

  4. 在VScode 中使用RT-Thread Studio初体验

    前言 工欲善其事,必先利其器,VScode是什么东东,想必大家都非常熟悉了,丰富的插件,有好的开发界面,是很多程序开发者的不二之选,RT-Thread竟然也开发了Vscode插件,真的是非常的nice ...

  5. 小目标增强(Augmentation for small object)

    小物体检测的增强 摘要:在近些年来,目标检测已经有了长足的进步.尽管有很大改进,但是在小目标和大目标检测性能方面还是有巨大的差距.我们在具有挑战性的数据集MS-COCO上分析了目前性能最好的模型Mas ...

  6. 「10.13」毛一琛(meet in the middle)·毛二琛(DP)·毛三琛(二分+随机化???)

    A. 毛一琛 考虑到直接枚举的话时间复杂度很高,我们运用$meet\ in\ the\ middle$的思想 一般这种思想看似主要用在搜索这类算法中 发现直接枚举时间复杂度过高考虑枚举一半另一半通过其 ...

  7. DOS命令行(6)——Windows网络状态及用户管理

    ipconfig --查看计算机中适配器的TCP/IP配置信息 命令格式: ipconfig [/allcompartments] [/? | /all | /renew [adapter] | /r ...

  8. 精通Proteus仿真器件制作(3)DLL仿真模型创建

    有些人可能会想:什么叫做"DLL仿真模型之原理图符号"?我想学高级的C++创建DLL(动态链接库)仿真模型的方式,你别拦着我,不然,我可就人挡Kill人,佛挡Kill佛啦!原理图符 ...

  9. vue中使用element-ui出现Couldn't find preset "es2015" relative to directory

    这是因为没有安装ES 标准 使用 npm install babel-preset-es2015 -d 安装之后就好了

  10. K8s 部署 Prometheus + Grafana

    一.简介 1. Prometheus 一款开源的监控&报警&时间序列数据库的组合,起始是由 SoundCloud 公司开发的 基本原理是通过 HTTP 协议周期性抓取被监控组件的状态, ...