Odoo的API装饰器

258 阅读5分钟

Odoo API模块定义了Odoo环境和方法修饰符。

odoo.api.autovacuum(method)

修饰一个方法,使其由日常vacuum的cron作业(模型ir.autovacuum)调用。这通常用于垃圾收集之类的不需要特定cron作业的任务。

odoo.api.constrains(args)

约束检查的装饰器。

每个参数必须是检查记录中使用的字段名:

@api.constrains('name', 'description')
def _check_description(self):
    for record in self:
        if record.name == record.description:
            raise ValidationError("Fields name and description must be different")

修改其中任意一个命名字段的记录就会调用。

如果验证失败,则应引发ValidationError

**警告**

@constrains仅支持简单的字段, 以点分隔的字段名字 (关系字段的字段 e.g. partner_id.customer)不支持,将被忽略。

仅当@constrains修饰的方法中声明的字段包含在create或write调用中时才会触发。 这意味着视图中不存在的字段在创建记录期间不会触发调用. 如果要出发必须重写create以确保始终触发约束(e.g. to test the absence of value).

也可以传递一个函数作为参数。在这种情况下,通过使用模型实例调用函数来提供字段名。

odoo.api.depends(args)

返回一个decorator,该decorator指定“compute”方法的字段依赖关系。每个参数必须是一个由点分隔的字段名序列组成的字符串:

pname = fields.Char(compute='_compute_pname')

@api.depends('partner_id.name', 'partner_id.is_company')
def _compute_pname(self):
    for record in self:
        if record.partner_id.is_company:
            record.pname = (record.partner_id.name or "").upper()
        else:
            record.pname = record.partner_id.name

也可以传递一个函数作为参数。在这种情况下,通过使用字段的模型调用函数来提供依赖关系。

odoo.api.depends_context(args)

返回一个修饰符,该修饰符指定非存储的“compute”方法的上下文依赖项。每个参数都是上下文字典中的一个键:

price = fields.Float(compute='_compute_product_price')

@api.depends_context('pricelist')
def _compute_product_price(self):
    for product in self:
        if product.env.context.get('pricelist'):
            pricelist = self.env['product.pricelist'].browse(product.env.context['pricelist'])
        else:
            pricelist = self.env['product.pricelist'].get_default_pricelist()
        product.price = pricelist._get_products_price(product).get(product.id, 0.0)

所有依赖项都必须是可哈希的。以下键具有特殊支持:

  • company (上下文或当前公司id中的值),

  • uid (当前用户id和超级用户标志),

  • active_test (env.context中的值或field.context中的值).

odoo.api.model(method)(github.com/odoo/odoo/b…)

修饰一个记录样式方法,其中self是一个记录集,但其内容不相关,只有模型相关。这样的方法:

@api.model
def method(self, args):
    ...

odoo.api.model_create_multi(method)

修饰一个方法,该方法获取字典列表并创建多个记录。可以使用单个dict或dict列表调用该方法:

record = model.create(vals)
records = model.create([vals, ...])

odoo.api.onchange(args)

返回一个decorator来修饰给定字段的onchange方法。

在出现字段的表单视图中,当修改某个给定字段时,将调用该方法。在包含表单中存在的值的伪记录上调用该方法。该记录上的字段赋值将自动发送回客户端。

每个参数必须是字段名:

@api.onchange('partner_id')
def _onchange_partner(self):
    self.message = "Dear %s" % (self.partner_id.name or "")
return {
    'warning': {'title': "Warning", 'message': "What is this?", 'type': 'notification'},
}

如果类型设置为通知,则警告将显示在通知中。否则,它将作为默认值显示在对话框中。

**警告**
@onchange仅支持简单字段名,不支持点名称(关系字段的字段 e.g. `partner_id.tz`) 将被忽略
**危险**
由于@onchange返回伪记录的记录集,因此对上述记录集调用任何一个CRUD方法(create()、read()、write()、unlink())都是未定义的行为,因为它们可能还不存在于数据库中。
相反,只需像上面的示例中所示那样设置记录的字段,或者调用update()方法。
**警告**
one2manymany2many字段不可能通过onchange修改自身。这是一个Web客户端限制 - see ![**\#2693**](https://github.com/odoo/odoo/issues/2693)

odoo.api.ondelete(*, at_uninstall)

标记要在unlink()期间执行的方法。

此装饰器的目标是,如果从业务角度来看,删除记录没有意义,则在取消链接记录时允许客户端错误。例如,用户不能删除已验证的销售订单。

虽然这可以通过简单地重写模型上的方法unlink来实现,但它的缺点是与模块卸载不兼容。卸载模块时,重写可能会引发用户错误,但我们不必担心,因为模块正在卸载,因此无论如何都应该删除与模块相关的所有记录。

这意味着通过重写unlink,很可能会有一些表/记录保留为卸载模块中的剩余数据。这会使数据库处于不一致的状态。此外,如果在该数据库上重新安装模块,则存在冲突的风险。

用@ondelete修饰的方法应在某些条件下引发错误,按照惯例,该方法应命名为_unlink_if_<condition>_unlink_except_<not_condition>.

@api.ondelete(at_uninstall=False)
def _unlink_if_user_inactive(self):
    if any(user.active for user in self):
        raise UserError("Can't delete an active user!")

# same as above but with _unlink_except_* as method name
@api.ondelete(at_uninstall=False)
def _unlink_except_active_user(self):
    if any(user.active for user in self):
        raise UserError("Can't delete an active user!")
  • Parameters at_uninstall (bool) – 如果正在卸载实现所述方法的模块,是否应调用修饰方法。几乎应始终为False,以便模块卸载不会触发这些错误。
**危险**
只有当卸载模块时,您正在执行的检查也适用时,参数at_uninstall才应设置为True。
例如,在卸载sale时,是否删除已验证的销售订单并不重要,因为无论如何都应删除与sale相关的所有数据,在这种情况下,at_uninstall应设置为False。
但是,如果没有安装其他语言,则阻止删除默认语言是有意义的,因为删除默认语言会破坏许多基本行为。在这种情况下,at_uninstall应设置为True

odoo.api.returns(model, downgrade=None, upgrade=None)

为返回model实例的方法返回修饰符。

  • Parameters

    • model – 模型名称,或当前模型的self

    • downgrade – 一个函数downgrade(self,value,*args,**kwargs),用于将记录样式value转换为传统样式输出

    • upgrade – 函数upgrade(self,value,*args,**kwargs)将传统样式value转换为记录样式输出

参数self*args**kwargs是以记录样式传递给方法的参数。

装饰器将方法输出调整为api样式:传统样式为ididsFalse,记录样式为记录集:

@model
@returns('res.partner')
def find_partner(self, arg):
    ...     # return some record

# output depends on call style: traditional vs record style
partner_id = model.find_partner(cr, uid, arg, context=context)

# recs = model.browse(cr, uid, ids, context)
partner_record = recs.find_partner(arg)

请注意,修饰方法必须满足该约定。

这些修饰器是自动inherited:重写修饰的现有方法的方法将用相同的@return(model)修饰。

欢迎关注公众号

公众号.jpeg