跳至内容

老赵解读Odoo 18开发教程10:约束与数据质量

2026年8月15日
老赵解读Odoo 18开发教程10:约束与数据质量

原文:Odoo 18 官方开发教程“Server framework 101”第 10 章。本文尽量保留原文结构、代码、练习与图片,仅进行中文翻译,并在文末增加“老赵解读”。

第10章:约束


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

Odoo 提供了两种设置自动验证不变量的方法:
Python constraints
SQL constraints

SQL

参考:与该主题相关的文档可以在以下位置找到
模型PostgreSQL 的文档 中。

说明

目标: 在本节末尾:

  • 金额应该(严格)为正数

Constraints on amounts

  • 房产类型和标签应该有唯一的名称

Constraints on names

SQL 约束通过模型属性定义
_sql_constraints。该属性被分配了一个列表
包含字符串 (name, sql_definition, message) 的三元组,其中 name
有效的 SQL 约束名称,sql_definition表约束 表达式
message 是错误消息。

你可以找到一个简单的例子
这里

练习

添加 SQL 约束。

将以下约束添加到其对应的模型中:

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

提示:在 Odoo 代码库中搜索 unique 关键字以获取唯一名称的示例。

使用 -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)

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

蟒蛇

参考:与该主题相关的文档可以在以下位置找到
constrains()

说明

目标:在本节末尾,将无法接受报价
低于预期价格的90%。

Python constraint

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%。

提示:在报价被验证之前,销售价格为零。你需要微调你的
检查以考虑到这一点。

警告

始终使用 float_compare()
float_is_zero() 来自 odoo.tools.float_utils 的方法
使用花车!

确保每次销售价格或预期价格发生变化时都会触发约束!

SQL 约束通常比 Python 约束更有效。当性能很重要时,始终
与 Python 约束相比,更喜欢 SQL。

我们的房地产模块开始看起来不错。我们添加了一些业务逻辑,现在我们确保
数据是一致的。然而,用户界面仍然有点粗糙。让我们看看如何
下一章 中改进它。

老赵解读

约束是业务规则的最后防线。SQL 约束适合数据库能够直接表达的唯一性和数值规则,Python 约束适合跨字段、跨记录或需要业务判断的校验。

不要只在界面上限制错误输入,因为数据还可能来自导入、接口和自动化任务。约束应给出用户能理解的中文错误信息,同时注意已有脏数据会导致模块升级失败,部署前要先检查和清理。

老赵解读Odoo 18开发教程09:业务动作