如何使用odoo的compute方法,自动计算odoo字段
前言
在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
总结
- odoo的compute可以实现我们对数据字段自动计算的需求。
- fields中加入store属性可以实现数据的持久化存储。
- compute计算字段在持久化存储之后不会在自动计算,需要我们配合depends来监听指定计算字段在数据改动的时候重新计算数据字段。
- inverse方法可以帮助我们解决compute计算字段readonly的问题,并在输入对应的字段进行逆向计算之前的字段。
- compute字段默认是store为False的所有search是无效的,还可以指定search的方式实现搜索。这里就不去细讲了,很简单也不常用。
- 还有compute_sudo属性可以设置字段在使用的时候是否以超级管理员的方式来进行计算,这里store=True的时候默认为True,否则默认为False,了解一下就可以了。
- 如果有问题可以在下方留言。
如何使用odoo的compute方法,自动计算odoo字段的更多相关文章
- odoo开发基础--模型之基本字段类型
定义模型的时候,和python的其他框架类似,可以对比Django,同样是一个模型即:一个class对应生成数据库中的一张表, 只是odoo的继承机制比较复杂一点,在日常的开发中,定义模型的时候, 基 ...
- C#中DataTable中的Compute方法使用收集
原文: C#中DataTable中的Compute方法使用收集 Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详 ...
- [datatable]借助DataTable的Compute方法
借助DataTable的Compute方法,DataTable中数据不用事先排好序. 下面代码中的dt是跟前面的是一样的 DataTable dtName = dt.DefaultView.ToTab ...
- C# DataTable Compute方法的使用
在开发中需要对DataTable的数据进行处理,比如累加,求最大最小及平均值等,以前都采用手工对DataTable进行循环并计算的方式,现在发现DataTable的Compute方法可以轻松实现这些功 ...
- 给 odoo 的 bom 明细加上位置字段
给 odoo 的 bom 明细加上位置字段 odoo 的 BOM 明细没有位置字段,这可无法用于电子生产中. 摸索了几天,找了一些教程,最终实现了. 在模型中找到 mrp_bom_line 增加自定义 ...
- c# 基于DataTable的Compute方法的扩展
DataTable.Compute(String, String) 方法 定义 命名空间:System.Data 程序集:System.Data.dll, netstandard.dll, Syste ...
- 转载 C#中DataTable中的Compute方法使用收集
原文: C#中DataTable中的Compute方法使用收集 Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详 ...
- LINQ找出重复和不重复的元素及linq OrderBy 方法 两个字段同时排序有关问题
//重复元素:3,4,5 //不重复元素:1,8,9 , , , , , , , , , , }; //不重复元素 var unique = arr.GroupBy(i => i) .Where ...
- 【转载】Sqlserver使用IsNull方法对空字段进行赋值操作
在Sqlserver的SQL语句查询过程或者编写存储过程以及自定义函数过程中,有时候字段的值为空,如果为空的字段需要赋值一个默认值,可以使用Sqlserver内置系统函数IsNull来给定一个默认值, ...
随机推荐
- BlazorCharts 原生图表库的建设历程
作者:陈超超 Ant Design Blazor 项目贡献者,拥有十多年从业经验,长期基于.Net技术栈进行架构与开发产品的工作,现就职于正泰集团. 邮箱:timchen@live.com 欢迎各位读 ...
- 深入理解java虚拟机笔记Chapter3-内存分配策略
内存分配策略 新生代和老年代的 GC 操作 新生代 GC 操作:Minor GC 发生的非常频繁,速度较块. 老年代 GC 操作:Full GC / Major GC 经常伴随着至少一次的 Minor ...
- Lombok——一款Java构建工具,“懒人”必备!!(idea版)
一.简介 Lombok 是一种 Jav 构建工具,可用来帮助开发人员消除 Java 的冗长代码,尤其是对于简单的 Java 对象(POJO).它是通过注解实现这一目的. 二.使用 1.在idea中安装 ...
- python django中restful框架的使用
在使用django进行前后台分离开发时通常会搭配django-rest-framework框架创建RESTful风格的接口API.框架介绍及版本要求可参考官方地址:https://www.django ...
- sys用户无法远程登陆
1.用sys用户远程登陆 [oracle@edbjr2p2 admin]$ sqlplus system/oracle@PROD3 as sysdbaSQL*Plus: Release 11.2.0. ...
- Java语言实现二维码的生成
众所周知,现在生活中二维码已经是无处不见.走在街道上,随处可见广告标语旁有二维码,手机上QQ,微信加个好友都能通过二维码的方式,我不知道是什么时候兴起的二维码浪潮,但是我知道,这在我小时候可是见不到的 ...
- C# 位图BitArray 小试牛刀
前面聊了布隆过滤器,回归认识一下位图BitMap,阅读前文的同学应该发现了布隆过滤器本身就是基于位图,是位图的一种改进. 位图 先看一个问题, 假如有1千万个整数,整数范围在1到1亿之间,如何快速确定 ...
- SQL修改表约束实现
先删除表约束 Alter Table 表名 Drop Constraint 约束名 然后再新建约束(加上级联删除) Alter Table Table_Name Add Constraint FK_T ...
- iOS-block本质是什么?
一: block的原理是怎样的?本质是什么? block本质上也是一个OC对象,因为它的内部也有个isa指针 block是封装了函数调用以及函数调用环境的OC对象 接下来我们将通过底层源码来论证上诉两 ...
- 在C++中,你真的会用new吗?
摘要:"new"是C++的一个关键字,同时也是操作符.关于new的话题非常多,因为它确实比较复杂,也非常神秘. 本文分享自华为云社区<如何编写高效.优雅.可信代码系列(2)- ...