如何使用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来给定一个默认值, ...
随机推荐
- PyQt5开发实践(一、准备篇)
前言 近一年来我开发了不少PyQt小项目,因为之前没用过使用C++语言的Qt,所以可以算是从零基础开始边学边做的,这个过程中再一次体会到国内技术社区的匮乏-- 国内关于PyQt的资料说少不少,说多也不 ...
- 【NX二次开发】Block UI 列表框
属性说明 常规 类型 描述 BlockID String 控件ID Enable Logical 是否可操作 Group Logical ...
- Spring Cloud Alibaba(15)---Sleuth+Zipkin
SpringCloudAlibaba整合Sleuth+Zipkin 有关Sleuth之前有写过两篇文章 Spring Cloud Alibaba(13)---Sleuth概述 Spring Cloud ...
- Activity侧滑返回的实现原理
简介 使用侧滑Activity返回很常见,例如微信就用到了.那么它是怎么实现的呢.本文带你剖析一下实现原理.我在github上找了一个star有2.6k的开源,我们分析他是怎么实现的 //star 2 ...
- org.junit.Assert(断言)
org.junit.Assert(断言) Assert是断言的意思,可以理解为"猜测",如果猜测错误,则抛出java.lang.AssertionError异常. 引入jar包 ...
- redis学习第一天
不同于其他的常用关系型数据库,redis是一个非常轻便,体积小,存放键值对的数据库,常用于构建高性能,可扩展的Web应用程序. 这是我第一次接触redis,之前没有使用过,只听说过.因为刚毕业,找工作 ...
- Unity StateMachineBehaviour
在unity animator中单个Animator Clip中点击Add Behaviour增加当执行该动画时的一些状态代码,请看如下 创建完之后基本代码结构如下:(如果想修改默认代码结构,请看示例 ...
- Weblogic下的servlet内存马注入-无参照纯调试
目录 1.寻找servlet注入方法 1.1 调试 1.2 servletMapping添加servlet 2.获取request 2.1 从当前线程寻找信息 2.2 JNDI注入到内存马注入 3.关 ...
- 19、高可用工具heartbeat介绍
19.1.heartbeat的作用: heartbeat的官方网站地址是:http://linux-ha.org/wiki/Main_Page 19.2.heartbeat工作原理: 19.3.hea ...
- 16、linux下卸载oracle11gR2
提示:如果要再次安装, 最好先做一些备份工作,包括用户的登录脚本,数据库自动启动关闭的 脚本,和Listener自动启动的脚本,要是有可能连创建数据库的脚本也保存下来: 16.1.通过oracle自带 ...