约束(Constraints)

上一章介绍了向模型中添加一些业务逻辑的能力。我们现在可以将按钮链接到业务代码,但如何防止用户输入错误的数据?例如,在我们的房地产模块中,没有什么可以阻止用户设置负预期价格。

odoo提供了两种设置自动验证恒定式的方法:Python约束 and SQL约束

SQL

参考:与此主题相关的文档可以查看 ModelsPostgreSQL文档

我们通过模型属性_sql_constraints来定义SQL约束,该属性被赋值为一个包含三元组(name, sql_definition, message)的列表,其中name为一个合法的SQL约束名称, sql_definition表约束表达式,message为错误消息。

一个简单的示例

class AccountAnalyticDistribution(models.Model):
_name = 'account.analytic.distribution'
_description = 'Analytic Account Distribution'
_rec_name = 'account_id' account_id = fields.Many2one('account.analytic.account', string='Analytic Account', required=True)
percentage = fields.Float(string='Percentage', required=True, default=100.0)
name = fields.Char(string='Name', related='account_id.name', readonly=False)
tag_id = fields.Many2one('account.analytic.tag', string="Parent tag", required=True) _sql_constraints = [
('check_percentage', 'CHECK(percentage >= 0 AND percentage <= 100)',
'The percentage of an analytic distribution should be between 0 and 100.')
]

一个简单的示例--唯一约束

class BlogTagCategory(models.Model):
_name = 'blog.tag.category'
_description = 'Blog Tag Category'
_order = 'name' name = fields.Char('Name', required=True, translate=True)
tag_ids = fields.One2many('blog.tag', 'category_id', string='Tags') _sql_constraints = [
('name_uniq', 'unique (name)', "Tag category already exists !"),
]

练习--添加SQL约束

添加以下约束到对应模型:

  • 房产预期价格必须为正数
  • 房产售价必须为正数
  • 报价必须为正数
  • 房产标签名称和类型名称必须唯一

使用-u estate选项重新启动服务器以查看结果。请注意,可能存在阻止设置SQL约束的数据。可能会弹出类似以下内容的错误消息:

ERROR rd-demo odoo.schema: Table 'estate_property_offer': unable to add constraint 'estate_property_offer_check_price' as CHECK(price > 0)

例如,如果某些报价的价格为零,则无法应用约束。可以删除、修正有问题的数据以应用新的约束。

修改odoo14\custom\estate\models\estate_property.py,添加SQL约束

    _sql_constraints = [
('check_expected_price', 'CHECK(expected_price > 0)', 'expected price should be positive.'),
('check_selling_price', 'CHECK(selling_price > 0)', 'selling price should be positive.')
]

注意:当selling_price为null时,也通过CHECK(selling_price > 0)校验的

修改odoo14\custom\estate\models\estate_property_tag.py,添加SQL约束

    _sql_constraints = [('check_tag', 'unique(name)', 'Tag name must be unique !')]

修改odoo14\custom\estate\models\estate_property_type.py,添加SQL约束

    _sql_constraints = [('check_name', 'unique(name)', 'Type name must be unique !')]

重启服务验证

预期效果动画:https://www.odoo.com/documentation/14.0/zh_CN/_images/sql_01.gif

https://www.odoo.com/documentation/14.0/zh_CN/_images/sql_02.gif

Python

参考: 主题关联文档可查看constrains().

SQL约束是确保数据一致性的有效方法。然而,可能需要进行更复杂的检查,这需要Python代码。在这种情况下,我们需要一个Python约束。

Python约束定义为用 constrains()修饰的方法,并在记录集上调用。修饰符指定约束中涉及哪些字段。当修改这些字段中的任何字段时,将自动计算约束。如果不满足该方法的恒定式,则该方法将引发异常:

from odoo.exceptions import ValidationError
... @api.constrains('date_end')
def _check_date_end(self):
for record in self:
if record.date_end < fields.Date.today():
raise ValidationError("The end date cannot be set in the past")
# all records passed the test, don't return anything

一个简单的示例

    @api.constrains('quantity')
def check_quantity(self):
for quant in self:
if quant.location_id.usage != 'inventory' and quant.lot_id and quant.product_id.tracking == 'serial' \
and float_compare(abs(quant.quantity), 1, precision_rounding=quant.product_uom_id.rounding) > 0:
raise ValidationError(_('The serial number has already been assigned: \n Product: %s, Serial Number: %s') % (quant.product_id.display_name, quant.lot_id.name))

练习--添加Python约束

添加售价不能低于预期价格90%的约束

提示: 报价生效前,保持售价为0。你需要对校验进行微调,以便把这个考虑在内。

警告

当和浮点数打交道时,总是使用从 odoo.tools.float_utils导入的float_compare()float_is_zero()方法

确保每次售价或者预期价格改变时,自动触发约束

修改odoo14\custom\estate\models\estate_property.py

导入 ValidationError

from odoo.exceptions import ValidationError

最末尾添加以下代码

    @api.constrains('selling_price', 'expected_price')
def _check_selling_price(self):
for record in self:
if record.selling_price < self.expected_price * 0.9:
raise ValidationError("selling price can`t not lower then 90 percent of expected price")

重启服务,浏览器中验证

预期效果动画:https://www.odoo.com/documentation/14.0/zh_CN/_images/python.gif

SQL约束通常比Python约束更效率。当性能很重要时,总是首选SQL约束而不是Python约束。

odoo 开发入门教程系列-约束(Constraints)的更多相关文章

  1. ActiveMQ详细入门教程系列(一)

    一.什么是消息中间件 两个系统或两个客户端之间进行消息传送,利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排队模型,它可以在分布式环境下 ...

  2. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

  3. Android Studio JNI开发入门教程

    Android Studio JNI开发入门教程 2016-08-29 14:38 3269人阅读 评论(0) 收藏 举报  分类: JNI(3)    目录(?)[+]   概述 在Andorid ...

  4. SeaJS入门教程系列之使用SeaJS(二)

    SeaJS入门教程系列之使用SeaJS(二) 作者: 字体:[增加 减小] 类型:转载 时间:2014-03-03我要评论 这篇文章主要介绍了SeaJS入门教程系列之使用SeaJS,着重介绍了SeaJ ...

  5. 移动H5开发入门教程:12点webAPP前端开发经验

    如果你是一名移动H5前端开发人员,25学堂的小编认为下面的分享的12点webAPP前端开发经验是你必须掌握的基础知识点.算是一篇移动H5开发入门教程吧! 1. viewport:也就是可视区域.对于桌 ...

  6. Silverlight,Windows 8应用开发实例教程系列汇总

    Kevin Fan分享开发经验,记录开发点滴 Silverlight,Windows 8应用开发实例教程系列汇总 2012-06-18 01:05 by jv9, 2145 阅读, 3 评论, 收藏, ...

  7. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  8. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  9. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  10. 基于Nodejs生态圈的TypeScript+React开发入门教程

    基于Nodejs生态圈的TypeScript+React开发入门教程   概述 本教程旨在为基于Nodejs npm生态圈的前端程序开发提供入门讲解. Nodejs是什么 Nodejs是一个高性能Ja ...

随机推荐

  1. 2月22日javaweb学习之Maven

    Maveb是专门用于管理和构建java项目的工具,它的主要功能有: 1.提供一套标准化的项目结构. 2.提供一套标准化的构建流程(编译.测试.打包.发布......) 3.提供了一套依赖管理机制 Ma ...

  2. ArrayList 的toArray的转换数组方法的注意事项

    ArrayList 的toArray的转换数组方法的注意事项 toArray()一共有两个方法 toArray(T[] a) 和toArray() 源码是 进行使用toArray()方法时候,使用 ( ...

  3. java不返回某些字段,包括 null

    一.使用 fastjson 包. (1) SimplePropertyPreFilter 可以将需要的字段留下来. import com.alibaba.fastjson.JSON;import co ...

  4. axis2 WebService 请求参数xml格式

    方法定义 public class GetBillInfoService { public String getBillList(String xmlData, String temp ){} 传入接 ...

  5. Django: sqlite的版本问题小记 “SQLite 3.8.3 or later”

    问题概述 在Django中,默认的数据库时SQLite3. 可能会出现sqlite版本问题的报错,具体如下 起初我直接在django的project下面开了个cmd窗口,python python m ...

  6. SQL语句底层执行顺序

    1. SELECT 语句的完整结构 SQL92语法: SELECT ...,....,(存在聚合函数) FROM ...,...,... WHERE 多表的连接条件 AND 不包含聚合函数的过滤条件 ...

  7. 3D max安装

    ​  一.安装包获取 下载前关闭电脑保护,病毒查杀等功能,因为注册机会被认为是病毒处理!!! 3dmax2018(64位)下载链接:https://pan.baidu.com/s/1dDsRW9XQa ...

  8. Glinux 1395 build ENV setup

    1.安装ubuntu 14.04.05 LTS 64bit 2.初始化root 密码 sudo passwd  Password: <--- 输入安装时那个用户的密码  Enter new UN ...

  9. recovery gerrit

    参考wiki :https://wiki.realtek.com/pages/viewpage.action?pageId=81823331 1.修改IP: for example : Gerrit/ ...

  10. vue中小写数字转大写汉字

    numTocoggle(money){ //汉字的数字 var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖') ...