odoo17开发教程(16):制约因素


前言

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

Odoo 提供了两种设置自动验证不变式的方法:Python 约束和 SQL 约束。


提示:以下是本篇文章正文内容,下面案例可供参考

一、SQL约束

约束通过模型属性 _sql_constraints 进行定义。该属性被分配给一个包含字符串(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.')
    ]

实践:

添加 SQL 约束。

在相应的模型中添加以下约束:

  • 房地产预期价格必须为严格正值
  • 房产售价必须为正值
  • 出价必须严格为正
  • tag名称和房产类型名称必须是唯一的

在estate_property模型中添加:

_sql_constraints = [
        ("check_expected_price", "CHECK(expected_price > 0)", "期望价格必须为正"),
        ("check_selling_price", "CHECK(selling_price > 0)", "销售价格必须为正")
    ]

estate_property_type模型中添加:

_sql_constraints = [
        ("check_name", "UNIQUE(name)", "房产类型必须是唯一的")
    ]

 添加约束以后,再添加相同的type,就会提示错误

二、PYTHON约束

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

 实践

添加 Python 约束。

添加一个约束条件,使销售价格不能低于预期价格的 90%。

提示:在报价生效之前,售价为零。您需要对检查进行微调,以考虑到这一点。

    @api.constrains('selling_price')
    def _check_selling_price(self):
        for record in self:
            # 使用 float_is_zero 检查销售价格是否为0,考虑浮点数精度
            if float_is_zero(record.selling_price, precision_digits=2):
                continue

            # 计算期望价格的90%
            min_allowed_price = record.expected_price * 0.9

            # 使用 float_compare 比较销售价格和期望价格的90%
            # 如果销售价格小于期望价格的90%,float_compare 返回 -1
            if float_compare(record.selling_price, min_allowed_price, precision_digits=2) < 0:
                raise ValidationError("The selling price cannot be lower than 90% of the expected price.")

SQL 约束通常比 Python 约束更有效。在性能方面,SQL 约束比 Python 约束更有优势。

我们的房地产模块开始变得不错。我们添加了一些业务逻辑,现在我们要确保数据的一致性。不过,用户界面还有点粗糙。让我们在下一章看看如何改进它。

上一篇 odoo17开发教程(15):增加一些动作和按钮-CSDN博客

下一篇 odoo17开发教程(17):美化UI界面

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值