如何使用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来给定一个默认值, ...
随机推荐
- python_reques接口测试框架,Excel作为案例数据源
一.框架菜单 1.1 common模块 1.2 其他 二.Excel接口测试案例编写 三.读取Excel测试封装(核心封装) excel_utils.py 读取Excel中的数据 import o ...
- JUC 并发编程--02,生产者和消费者 synchronized的写法 , juc的写法. Condition的用法
synchronized的写法 class PCdemo{ public static void main(String[] args) { //多个线程操作同一资源 Data data = new ...
- 重新整理 mysql 基础篇————— mysql 事务[三]
前言 简单整理一下事务. 正文 事务有四大特性: 1.原子性(atomicity) 一个事务必须被视为一个不可分割的最小单元. 2.一致性(consistency) 数据库总是从一个一致性的状态转换到 ...
- Redis 面试题 - 收藏版 (持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 如何基于 String 实现同步锁?
如何基于String实现同步锁? 在某些时候,我们可能想基于字符串做一些事情,比如:针对同一用户的并发同步操作,使用锁字符串的方式实现比较合理. 因为只有在相同字符串的情况下,并发操作才是不被允许的. ...
- XML从入门到深入(超详细)
一:什么是XML XML (eXtensible Markup Language)指可扩展标记语言,标准通用标记语言的子集,简称XML.是一种用于标记电子文件使其具有结构性的标记语言. XML可以标记 ...
- 基于Ubuntu下以Docker方式gitlab软件的部署
基于Ubuntu下以Docker方式gitlab软件的部署 目录 基于Ubuntu下以Docker方式gitlab软件的部署 1.安装Docker Compose 1.1 下载curl 1.2 安装c ...
- 聊聊IOC中依赖注入那些事 (Dependency inject)
What is Dependency injection 依赖注入定义为组件之间依赖关系由容器在运行期决定,形象的说即由容器动态的将某个依赖关系注入到组件之中在面向对象编程中,我们经常处理的问题就是解 ...
- Simpleperf分析之Android系统篇
[译]Simpleperf分析之Android系统篇 译者按: Simpleperf是用于Native的CPU性能分析工具,主要用来分析代码执行耗时.本文是主文档的一部分,系统篇. 原文见aosp仓库 ...
- Linux系统安装-C7
1.安装部署操作系统 (1)创建虚拟机,加载系统镜像 (2)进入系统引导界面进行配置 补充:centos7系统网卡名称 默认系统的网卡名称为 eth0 eth1 –centos6 默认系统的网卡名称为 ...