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