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 |开瓶器?的主要内容,如果未能解决你的问题,请参考以下文章