odoo17开发教程(14):Computed Fields And Onchanges

目录

概述:

计算字段Computed Fields

依赖关系

实践:

计算总面积

计算最佳报价。

Inverse Function反函数

实践:计算报价的有效日期。

其他信息

Onchanges

实践:设置花园面积和方向值。

如何使用它们?


概述:

模型之间的关系是任何 Odoo 模块的关键组成部分。任何业务案例的建模都离不开它们。然而,我们可能希望在给定模型内的字段之间建立联系。有时,一个字段的值由其他字段的值决定,有时,我们希望帮助用户输入数据。

计算字段和 onchanges 概念支持这些情况。虽然本章在技术上并不复杂,但这两个概念的语义非常重要。这也是我们第一次编写 Python 逻辑。到目前为止,除了类定义和字段声明之外,我们还没有写过其他东西。

计算字段Computed Fields

参考:有关此主题的文档可在计算字段的文档中找到。

在房地产模块中,我们定义了居住面积和花园面积。因此,将总面积定义为这两个字段的总和是很自然的。为此,我们将使用计算字段的概念,即某个字段的值将根据其他字段的值计算得出。

到目前为止,字段都是直接存储在数据库中或直接从数据库中检索的。字段也可以计算。在这种情况下,字段的值不是从数据库中检索出来的,而是通过调用模型的方法即时计算出来的。

要创建计算字段,请创建一个字段并将其属性 compute 设置为方法名称。计算方法应为 self 中的每条记录设置计算字段的值。

按照惯例,计算方法是私有的,这意味着它们不能从表现层调用,只能从业务层调用(参见第 1 章:架构概述)。私有方法的名称以下划线 _ 开头。

依赖关系

计算字段的值通常取决于计算记录中其他字段的值。ORM 希望开发人员使用装饰器 depends()在计算方法中指定这些依赖关系。只要字段的某些依赖项被修改,ORM 就会使用给定的依赖项来触发字段的重新计算:

from odoo import api, fields, modelsclass TestComputed(models.Model):_name = "test.computed"total = fields.Float(compute="_compute_total")amount = fields.Float()@api.depends("amount")def _compute_total(self):for record in self:record.total = 2.0 * record.amount

📔提示

self是一个集合。

对象 self 是一个记录集,即记录的有序集合。它支持标准的 Python 集合操作,如 len(self) 和 iter(self),以及额外的集合操作,如 recs1 | recs2。

对 self 进行迭代会逐条得到记录,其中每条记录本身就是一个大小为 1 的集合。您可以使用点符号访问/分配单条记录上的字段,例如 record.name。

实践:

计算总面积

在 estate.property 中添加 total_area 字段。它的定义是居住面积和花园面积之和。

计算最佳报价。

在 estate.property 中添加 best_price 字段。它被定义为报价中的最高价(即最大值)。

修改estate_perperty模型为如下代码:

class EstateProperty(models.Model):_name = "estate_property"_description = "Estate Property"def _get_default_date_available(self):# 使用 fields.Date.today() 获取当前日期,并添加三个月return fields.Date.today() + relativedelta(months=+3)name = fields.Char(required=True, default="Unknown")description = fields.Char(compute="_compute_description", store=True)postcode = fields.Char()date_available = fields.Date(copy=False, default=_get_default_date_available)expected_price = fields.Float(required=True)selling_price = fields.Float(readonly=True, copy=False)bedrooms = fields.Integer()living_area = fields.Integer()facades = fields.Integer()  # 外墙garage = fields.Boolean()garden = fields.Boolean()garden_area = fields.Integer()garden_orientation = fields.Selection([("north", "North"),("south", "South"),("east", "East"),("west", "West"),])active = fields.Boolean(default=True)state = fields.Selection([("new", "New"),("offer_received", "Offer Received"),("offer_accepted", "Offer Accepted"),("sold", "Sold"),("canceled", "Canceled"),], default="new", copy=False)property_type_id = fields.Many2one("estate_property_type", string="Property Type")user_id = fields.Many2one("res.users", string="Salesperson", default=lambda self: self.env.user)partner_id = fields.Many2one("res.partner", string="Partner", copy=False)tag_ids = fields.Many2many("estate_property_tag", string="Tags")offer_ids = fields.One2many("estate_property_offer", "property_id", string="Offers")total_area = fields.Integer(compute="_compute_total_area")best_price = fields.Float(compute="_compute_best_price", string="Best Price")@api.depends("offer_ids")def _compute_best_price(self):for record in self:record.best_price = max(record.offer_ids.mapped("price"))@api.depends("living_area", "garden_area")def _compute_total_area(self):for record in self:record.total_area = record.living_area + record.garden_area@api.depends("partner_id.name")def _compute_description(self):for record in self:record.description = "Test for partner %s" % record.partner_id.name

我们成功添加了Total Area和Best Price自动计算字段!

Inverse Function反函数

您可能已经注意到,计算字段默认为只读。这是意料之中的,因为用户不应该设置值。

在某些情况下,直接设置值可能还是有用的。在我们的房地产示例中,我们可以定义要约的有效期并设置有效日期。我们希望能够设置有效期或有效日期,其中一个会影响另一个。

为此,Odoo 提供了使用反函数的功能:

from odoo import api, fields, modelsclass TestComputed(models.Model):_name = "test.computed"total = fields.Float(compute="_compute_total", inverse="_inverse_total")amount = fields.Float()@api.depends("amount")def _compute_total(self):for record in self:record.total = 2.0 * record.amountdef _inverse_total(self):for record in self:record.amount = record.total / 2.0

计算方法设置字段,而反函数则设置字段的依赖。

⚠️请注意,逆方法在保存记录时被调用,而计算方法则在每次改变其依赖关系时被调用。

实践:计算报价的有效日期。

在 estate.property.offer 模型中添加以下字段:

Field

Type

Default

validity

Integer

7

date_deadline

Date

其中 date_deadline 是一个计算字段,定义为报价中两个字段的总和:创建日期和有效期。定义一个适当的反函数,以便用户可以设置日期或有效期。

其他信息
 

计算字段默认不存储在数据库中。因此,除非定义了搜索方法,否则无法对计算字段进行搜索。这一主题超出了本培训的范围,因此我们将不作介绍。在这里可以找到一个示例。

另一种解决方案是使用 store=True 属性存储字段。虽然这通常很方便,但要注意可能会给模型增加计算负荷。让我们重新使用我们的示例:

description = fields.Char(compute="_compute_description", store=True)
partner_id = fields.Many2one("res.partner")@api.depends("partner_id.name")
def _compute_description(self):for record in self:record.description = "Test for partner %s" % record.partner_id.name

每次更改合作伙伴名称时,都会自动重新计算提及该合作伙伴的所有记录的描述!当数百万条记录需要重新计算时,重新计算的费用很快就会过高。

还值得注意的是,一个计算字段可以依赖于另一个计算字段。ORM 足够聪明,可以按照正确的顺序正确地重新计算所有依赖关系......但有时会以降低性能为代价。

一般来说,在定义计算字段时必须始终牢记性能。要计算的字段越复杂(例如,有很多依赖关系或一个计算字段依赖于其他计算字段),计算所需的时间就越长。一定要事先花些时间评估计算字段的成本。大多数情况下,只有当你的代码到达生产服务器时,你才会意识到它拖慢了整个流程。这可不好 :-(

Onchanges

在我们的房地产模块中,我们还希望帮助用户输入数据。当设置 "花园 "字段时,我们希望给出花园面积和方向的默认值。此外,当 "花园 "字段未设置时,我们希望将花园面积重置为零,并删除朝向。在这种情况下,给定字段的值会修改其他字段的值。

onchange "机制为客户端界面提供了一种方法,只要用户填写了字段值,客户端界面就可以更新表单,而无需向数据库保存任何内容。为此,我们定义了一个方法,其中 self 代表表单视图中的记录,并用 onchange() 对其进行装饰,以指定由哪个字段触发。对 self 所做的任何更改都会反映在表单上:

from odoo import api, fields, modelsclass TestOnchange(models.Model):_name = "test.onchange"name = fields.Char(string="Name")description = fields.Char(string="Description")partner_id = fields.Many2one("res.partner", string="Partner")@api.onchange("partner_id")def _onchange_partner_id(self):self.name = "Document for %s" % (self.partner_id.name)self.description = "Default description for %s" % (self.partner_id.name)

实践:设置花园面积和方向值。

在 estate.property 模型中创建一个 onchange,以便在花园设置为 True 时设置花园面积 (10) 和朝向 (North) 的值。当未设置时,清除字段。

@api.onchange("garden")def _onchange_garden(self):if self.garden:self.garden_area = 10self.garden_orientation = "north"else:self.garden_area = 0self.garden_orientation = ""

如何使用它们?

对于计算字段和 onchanges 的使用没有严格的规定。

在很多情况下,使用计算字段和 onchanges 可以达到相同的效果。我们总是倾向于使用计算字段,因为它们也是在表单视图的上下文之外触发的。切勿使用 onchange 向模型添加业务逻辑。这是一个非常糟糕的想法,因为在以编程方式创建记录时,不会自动触发 onchange;它们只会在表单视图中触发。

使用存储的计算字段时,请密切注意其依赖关系。当计算字段依赖于其他计算字段时,更改一个值可能会触发大量的重新计算。这会导致性能低下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/278256.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漫谈5种注册中心

01 注册中心基本概念 1.1 什么是注册中心? 注册中心主要有三种角色: 服务提供者(RPC Server):在启动时,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。 服务消费者&…

鸿蒙开发学习:【OpenHarmony HAR】

OpenHarmony js/ts三方库使用的是OpenHarmony静态共享包,即HAR(Harmony Archive),可以包含js/ts代码、c库、资源和配置文件。通过HAR,可以实现多个模块或者多个工程共享ArkUI组件、资源等相关代码。HAR不同于HAP,不能独立安装运行…

Python数据分析-Matplotlib1

一、折线图的绘制 1.数据分析流程 2.运用Matplot绘制折线图 #encodingutf-8 import random from matplotlib import pyplot as plt #绘图工具库 from matplotlib import font_manager #解决中文显示问题 from cProfile import label #设置字体方式 my_font font_manager.Fon…

jscpd对项目进行查重(支持150+类语言)

jscpd jscpd 查重时能够跳过标记为忽略的块和新行以及空符号和注释&#xff08;不支持尖括号注释<!-- --&#xff01;>&#xff09;&#xff0c;重复率判定依据为一定长度标识符的MD5值是否相同。 安装 npm install -g jscpd配置参数(查看更多) OptionTypeDefaultDes…

挑战杯 机器视觉目标检测 - opencv 深度学习

文章目录 0 前言2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 0 前言 &#x1f5…

VS2019加QT5.14中Please assign a Qt installation in ‘Qt Project Settings‘.问题的解决

第一篇&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/aoxuestudy/article/details/124312629 error:There’ no Qt version assigned to project mdi.vcxproj for configuration release/x64.Please assign a Qt installation in “Qt Project Settings”. 一、分…

Docker学习之使用harbor搭建私有仓库(超详解析)

实验目的&#xff1a; 使用centos7&#xff0c;基于harbor构建私有仓库 实验步骤&#xff1a; 下载相关安装包和依赖&#xff1a; [rootlocalhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 wget //安装docker所需要的相关依赖 [rootlocalhost ~]#…

[ThinkPHP]Arr返回1

$detailId (int)Arr::get($detail, null); var_dump($detailId); 打印结果&#xff1a;int(1) 原因&#xff1a; vendor/topthink/think-helper/src/helper/Arr.php

如何定期清理数据库中的无效数据?

企业的数据库在运行相当长一段时间后&#xff0c;都会出现无效数据的堆积&#xff0c;这些数据包含了过时、重复、错误、缺失&#xff08;空字段&#xff09;的数据&#xff0c;长期占据着宝贵的数据库空间。而在上云热潮的推动下&#xff0c;绝大多数企业已经将他们的业务数据…

Linux第77步_处理Linux并发的相关函数

了解linux中的“原子整形数据”操作、“原子位数据”操作、自旋锁、读写锁、顺序锁、信号量和互斥体&#xff0c;以及相关函数。 并发就是多个“用户”同时访问同一个共享资源。如&#xff1a;多个线程同时要求读写同一个EEPROM芯片&#xff0c;这个EEPROM就是共享资源&#x…

2024全网最全Excel函数与公式应用

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 引言 Excel是一款广泛应用于商业、教育和个人…

某夕夕商品数据抓取逆向之webpack扣取

逆向网址 aHR0cHM6Ly93d3cucGluZHVvZHVvLmNvbQ 逆向链接 aHR0cHM6Ly93d3cucGluZHVvZHVvLmNvbS9ob21lL2JveXNoaXJ0 逆向接口 aHR0cHM6Ly9hcGl2Mi5waW5kdW9kdW8uY29tL2FwaS9naW5kZXgvdGYvcXVlcnlfdGZfZ29vZHNfaW5mbw 逆向过程 请求方式&#xff1a;GET 参数构成 【anti_content】…

基于SSM SpringBoot vue办公自动化计划管理系统

基于SSM SpringBoot vue办公自动化计划管理系统 系统功能 登录注册 个人中心 员工信息管理 部门信息管理 会议管理 计划管理 行程安排管理 行程进度管理 管理员管理 开发环境和技术 开发语言&#xff1a;Java 使用框架: SSM(Spring SpringMVC Mybaits)或SpringBoot 前端…

【题目】【网络系统管理】2022年甘肃省职业院校技能大赛-网络构建-试卷

极安云科专注职业教育技能竞赛培训4年&#xff0c;包含信息安全管理与评估、网络系统管理、网络搭建等多个赛项及各大CTF模块培训学习服务。本团队基于赛项知识点&#xff0c;提供完整全面的系统性理论教学与技能培训&#xff0c;成立至今持续优化教学资源与讲师结构&#xff0…

vivo统一接入网关VUA转发性能优化实践

作者&#xff1a;vivo 互联网服务器团队 - Qiu Xiangcun 本文将探讨如何通过使用Intel QuickAssist Technology&#xff08;QAT&#xff09;来优化VUA的HTTPS转发性能。我们将介绍如何使用QAT通过硬件加速来提高HTTPS转发的性能&#xff0c;并探讨QAT在不同应用场景中的表现。最…

Python下有关CV的一些算法和函数

目录&#xff1a; 1. HoughCircles二级目录三级目录 1. HoughCircles 霍夫圆检测 二级目录 三级目录

【CKA模拟题】查询消耗CPU最多的Pod

题干 For this question, please set this context (In exam, diff cluster name) 对于此问题&#xff0c;请设置此上下文&#xff08;在考试中&#xff0c;diff 集群名称&#xff09; kubectl config use-context kubernetes-adminkubernetesFind the pod that consumes the …

[云原生] Prometheus自动服务发现部署

一、部署服务发现 1.1 基于文件的服务发现 基于文件的服务发现是仅仅略优于静态配置的服务发现方式&#xff0c;它不依赖于任何平台或第三方服务&#xff0c;因而也是最为简单和通用的实现方式。 Prometheus Server 会定期从文件中加载 Target 信息&#xff0c;文件可使用 YAM…

大模型训练准备工作

一、目录 1 大模型训练需要多少算力&#xff1f; 2. 大模型训练需要多少显存&#xff1f; 3. 大模型需要多少数据量训练&#xff1f; 4. 训练时间估计 5. epoch 选择经验 6. 浮点计算性能测试 二、实现 1 大模型训练需要多少算力&#xff1f; 训练总算力&#xff08;Flops&…

逻辑运算函数

true默认为1 false默认为0 可以用于多条件筛选 if语句 多层嵌套