odoo 中何时使用 api.one 和 api.multi |开瓶器?

Posted

技术标签:

【中文标题】odoo 中何时使用 api.one 和 api.multi |开瓶器?【英文标题】:When to use api.one and api.multi in odoo | openerp? 【发布时间】:2015-03-15 07:54:49 【问题描述】:

最近 odoo(以前称为 OpenERP)V8 已经发布。在新的 API 方法中引入了装饰器。在models.py 方法中需要用@api.one@api.multi 装饰。

参考odoo documentation我无法确定确切的用途。谁能详细解释一下。

谢谢。

【问题讨论】:

【参考方案1】:

通常,两个 decoarators 都用于装饰记录样式的方法,其中 'self' 包含 recordset(s)。让我简单解释一下何时使用@api.one@api.multi

1. @api.one:

装饰一个记录样式的方法,其中 'self' 应该是一个单例实例。

装饰方法自动循环记录(即,对于记录集中的每条记录,它都会调用该方法),并将结果列成一个列表

如果方法用@returns 修饰,它会连接结果实例。这样的方法:

@api.one def 方法(自我,参数): 返回自己的名字

可以在记录和传统样式中调用,例如::

# recs = model.browse(cr, uid, ids, context)
names = recs.method(args)

names = model.method(cr, uid, ids, args, context=context)
每次将“self”重新定义为当前记录。

2. @api.multi:

装饰一个记录样式的方法,其中“self”是一个记录集。该方法通常定义对记录的操作。这样的方法:

@api.multi def 方法(self,args):

可以在记录和传统样式中调用,例如::

# recs = model.browse(cr, uid, ids, context)
recs.method(args)

model.method(cr, uid, ids, args, context=context)

何时使用:

    如果您使用@api.one,则返回值在列表中。 Web 客户端并不总是支持这一点,例如按钮动作 方法。 在这种情况下,您应该使用 @api.multi 来装饰您的方法,并可能调用 self.ensure_one() 方法定义。

    最好使用 @api.multi 和 self.ensure_one() 而不是 @api.one 以避免返回值的副作用。

【讨论】:

只要我看到方法装饰器允许指定您如何处理内部记录的语义信息。关于“何时使用 api.multi”这一点。这个标准是否基于 webclient 支持?这个问题在所有情况下都不能通过 api.return 解决?我看到我们牺牲了对 ORM 进行优化和决定正确调用有用的语义信息。我认为当ORM不支持某些操作而不是改进它时,就像使用越来越多的SQL语句一样。 @BomberMan 感谢您的详细解释!这解决了我的谜团:) 我想知道为什么我会从我的方法中收到一个列表:) 好答案!只想补充一点,自 v9.0 (odoo.com/documentation/10.0/reference/orm.html#module-odoo.api) 起,@api.one 已被弃用【参考方案2】:

@api.one

这个装饰器会自动为您在 RecordSet 的 Records 上循环。自我被重新定义为当前记录:

@api.one
def func(self):
    self.name = 'xyz'

@api.multi

Self 将是当前没有迭代的 RecordSet。这是默认行为:

@api.multi
def func(self):
    len(self)

所有API的详细说明可以参考Link

【讨论】:

【参考方案3】:
@api.model #When the record data/self is not as relevant. Sometimes also used with old API calls.
def model_text(self):
    return "this text does not rely on self"

@api.multi #Normally followed by a loop on self because self may contain multiple records
def set_field(self):
    for r in self:
        r.abc = r.a + r.b

@api.one #The api will do a loop and call the method for each record. Not preferred because of potential problems with returns to web clients
def set_field(self):
    self.abc = self.a + self.b

【讨论】:

请尽量避免仅仅将代码作为答案,并尝试解释它的作用和原因。对于没有相关编码经验的人来说,您的代码可能并不明显。

以上是关于odoo 中何时使用 api.one 和 api.multi |开瓶器?的主要内容,如果未能解决你的问题,请参考以下文章

odoo create 何时调用

ODOO 新API修饰符

odoo10学习笔记九:Odoo10 API

odoo10 api 装饰器

Odoo与浪潮合资研发PS Cloud之批号和序列号有什么区别

odoo开发中@api.depends与@api.onchange的区别