在很多场景下,需要对用户输入数据进行验证。比如编码不能重复,邮箱的准确性,手机号码规则,凡是不符合这些验证规则的数据,要报错并拒绝保存。在odoo中使用constraints(约束)来实现。odoo提供两种方式实现自动验证,python constraints和sql constraints
sql constraints
_sql_constraints = [
('name_description_check',
'CHECK(name != description)',
"名称和描述不能相同"),
('name_unique',
'UNIQUE(name)',
"已存在相同名称"),
]
sql constraints 通过模块属性_sql_constraints 进行定义。它是一个元组的列表,每个元组是一条数据约束(name, sql_definition, message),包含三个字符串元素:1)约束名称;2)约束规则(postgresql约束规则);3)违反约束规则时的警告信息。
注意,使用sql constraints,需要确保当前数据库里面没有违反该约束的数据,如果数据库中存在有违反约束的记录,那么在更新模块的时候系统日志里面会有警告信息并且constraints会添加失败。
python constraints
from odoo.exceptions import ValidationError
@api.constrains('age')
def _check_something(self):
for record in self:
if record.age > 20:
raise ValidationError("Your record is too old: %s" % record.age)
# all records passed the test, don't return anything
@api.constrains('instructor_id', 'attendee_ids')
def _check_instructor_not_in_attendees(self):
for r in self:
if r.instructor_id and r.instructor_id in r.attendee_ids:
raise exceptions.ValidationError("A session's instructor can't be an attendee")
python constraints,是通过装饰器@api.constrains(field_name,)来定义,每次记录修改的时候,如果包含装饰器定义的字段就会触发下面的方法,所以需要在方法里面判断是否违反约束,如果违反,则通过raise异常来弹出警告框并阻止记录保存。使用python constraints的时候就算是系统内已经有违反约束的记录也可以对新记录生效,并且里面的判断可以添加更加复杂的逻辑。
总的来说,sql constraints的效率较高,而python constraints使用更加灵活。