关注各种黑科技
B站UP主,编程教学,游戏玩家,挂B,金牛座

模型约束

odoo 中提供两种 建立约束的方式 1 python代码级别约束 2 SQL数据库级别约束

python代码约束

先来说说python代码级别的约束吧,因为是python代码级别,只要在model里写方法就可以实现。
from openerp.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
上面的代码使用constrains装饰器对 某个model的 age字段做了限制。当 记录中age字段 的值发生变化时, _check_something就会被调用。遍历所有的 记录(注意 这里的self是 一个recordset ,也就是对应多条记录), 做一些条件判断, 不满足就 抛出ValidationError异常,反应到用户界面上弹出一个警告框,导致用户保存失败。 练习 对课程的老师做检查,保证老师不出现在学生列表中。 openacademy/models.py
# -*- coding: utf-8 -*-
from openerp import models, fields, api, exceptions
class Session(models.Model):
    ...
    @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")
constrains参数的意思是,在这些字段发生改变时,进行检查。不会对原有的数据进行检查。

SQL约束

因为是在数据库中的约束,所以是在python约束之后执行。 通过 model的属性 _sql_constraints 写入规则列表 约束规则是一个 三元 元祖 格式 (name, sql_definition, message) name 此规则的名称 sql_definition 是 pgsql里的约束条件 参考 https://www.postgresql.org/docs/9.3/static/ddl-constraints.html message 定义报错信息 练习 给课程的name添加唯一检查和 与description不相同检查 openacademy/models.py
    session_ids = fields.One2many(
        'openacademy.session', 'course_id', string="Sessions")
    _sql_constraints = [
        ('name_description_check',
         'CHECK(name != description)',
         "The title of the course should not be the description"),
        ('name_unique',
         'UNIQUE(name)',
         "The course title must be unique"),
    ]
class Session(models.Model):
    _name = 'openacademy.session'
如果表里以及存在冲突的数据,导致sql约束更新不了。 练习 改写copy方法 来防止复制记录时, name相同,改写 Copy of name (x) 到 新的记录name openacademy/models.py
    session_ids = fields.One2many(
        'openacademy.session', 'course_id', string="Sessions")
    @api.multi
    def copy(self, default=None):
        default = dict(default or {})
        copied_count = self.search_count(
            [('name', '=like', u"Copy of {}%".format(self.name))])
        if not copied_count:
            new_name = u"Copy of {}".format(self.name)
        else:
            new_name = u"Copy of {} ({})".format(self.name, copied_count)
        default['name'] = new_name
        return super(Course, self).copy(default)
    _sql_constraints = [
        ('name_description_check',
         'CHECK(name != description)',
转载请注明出处
分享到: 更多 (0)

评论 0