odoo 开发入门教程系列-约束(Constraints)

约束(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

odoo 开发入门教程系列-约束(Constraints)

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

odoo 开发入门教程系列-约束(Constraints)

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

odoo 开发入门教程系列-约束(Constraints)

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

原文链接:https://www.cnblogs.com/shouke/p/17253382.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:odoo 开发入门教程系列-约束(Constraints) - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • Python中调用其他程序的方式详解

    Python中调用其他程序的方式详解 在Python中,我们经常需要调用其他的程序来实现特定的功能或者完成某些任务。通常遇到这种情况,我们可以使用os模块和subprocess模块提供的相关函数来实现对其他程序的调用操作。 使用os模块进行调用 os模块可以用来调用其他进程或者在当前进程中使用shell命令。使用os.system()函数可以简单地执行命令,…

    python 2023年5月31日
    00
  • python抖音表白程序源代码

    下面我来为您详细讲解“python抖音表白程序源代码”的完整攻略。 确认环境与安装必要依赖库 要使用抖音表白程序,我们需要确认以下两个前提条件: 安装Python环境,可前往Python官网下载安装:https://www.python.org/downloads/ 安装必要的依赖库,分别是requests与hashlib,可以在命令行中使用以下命令进行安装…

    python 2023年5月31日
    00
  • 如何使用Python在MySQL中修改表结构?

    要使用Python在MySQL中修改表结构,可以使用Python的内置模块sqlite3或第三方库mysql-connector-python。以下是使用mysql-connector-python在MySQL中修改表结构的完整攻略: 连接 要连接到MySQL,需要提供MySQL的主机、用户名、和密码。可以使用以下代码连接MySQL: mysql.conne…

    python 2023年5月12日
    00
  • C++和python实现阿姆斯特朗数字查找实例代码

    下面我会详细讲解“C++和Python实现阿姆斯特朗数字查找实例代码”的完整攻略,并且给出两条示例。阿姆斯特朗数字指的是一个n位数,它的每个数位的n次方之和等于它本身。比如说153是一个阿姆斯特朗数字,因为:$1^3 + 5^3 + 3^3 = 153$。 C++实现阿姆斯特朗数字查找 首先定义一个函数 isArmstrong(),用于判断一个数是否为阿姆斯…

    python 2023年5月20日
    00
  • Python中字符串对象语法分享

    Python中字符串对象语法分享 什么是字符串对象 字符串对象是Python中用于表示文本和字符序列的数据类型。在Python中,用一对单引号或双引号括起来的任何文本都可以作为字符串对象,例如: string1 = "Hello, world!" string2 = ‘Python for Beginners’ 字符串对象的基本操作 字符…

    python 2023年6月3日
    00
  • Python Socketserver实现FTP文件上传下载代码实例

    Python Socketserver实现FTP文件上传下载代码实例 本文主要介绍如何使用Python Socketserver实现简单的FTP文件传输服务,涉及TCP通信、文件上传下载等知识点。 一、Socketserver模块概述 Socketserver模块是Python标准库中的一个模块,它提供了在网络环境中编写简单协议和服务器的框架。该模块提供了使…

    python 2023年6月3日
    00
  • Python3中的列表,元组,字典,字符串相关知识小结

    Python3中的列表,元组,字典,字符串相关知识小结 在Python3中,列表、元组、字典和字符串是常见的数据类型。它们都有各自的特点和用途。本攻略将细介绍Python中列表、元组、字典和字符串的相关知识,并提供多个示例说明。 列表 列表是Python3中最常用的数据之一,它是一个有序的可变序列。列表可以包含任意类型的数据,包括数字、字符串、元组、列表、字…

    python 2023年5月13日
    00
  • 深入浅析Python的类

    深入浅析Python的类 为什么需要类 在程序设计中,我们往往需要定义多个变量,并对这些变量进行处理。如果我们一直使用单独的变量进行处理,会遇到一系列的问题。比如变量重名、代码冗长等等问题。为了避免这些问题,我们通常使用一种叫做“面向对象”的编程思想,将变量和对变量的操作进行打包,形成一个类。 类的基本概念 定义类 Python中定义类非常简单,以下是一个示…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部