首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@api.one,@api.multi和@api.model有什么区别?

@api.one,@api.multi和@api.model有什么区别?
EN

Stack Overflow用户
提问于 2015-06-29 09:54:27
回答 4查看 12.6K关注 0票数 11

我对Odoo的@api.one@api.multi@api.model感到困惑。

这三者之间有什么区别,它们的用例是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-06-29 10:28:47

当方法只在一个记录上被调用时,api.one就意味着要使用。它确保在使用api.one装饰器调用方法时没有多个记录。假设你有唱片partner = res.partner(1,)。它只是一个记录,并且有一些方法,例如(在res.partner中):

代码语言:javascript
复制
@api.one
def get_name(self):
    return self.name #self here means one record

这样称呼它是可行的:

代码语言:javascript
复制
partner.get_name()

但是如果有更多的记录,比如partners = res.partner(1, 2,)

调用它,会引发一个警告,告诉你只能在一个记录上调用它。对于多个记录,使用api.multi,其中self是记录集,可以遍历所有记录来执行某些操作。例如:

代码语言:javascript
复制
@api.multi
def get_partner_names(self):
    names = []
    for rec in self:
        names.append(rec.name)
    return ', '.join(names)

当您需要对模型本身做一些事情,而不需要修改/检查某些精确的模型记录/记录时,api.model被认为是使用的。例如,可以有方法返回一些有关模型结构的元信息或一些辅助方法等。在文档中,也有人说这个api在从旧api迁移时很好使用,因为它“礼貌地”将代码转换为新api。此外,在我自己的经验中,如果您需要返回某个东西的方法,model装饰器对它很有好处。api.one返回空列表,因此当使用api.one on方法时,当它应该返回某项内容时,它可能会导致意外行为。

更多信息:http://odoo-new-api-guide-line.readthedocs.org/en/latest/decorator.html

票数 7
EN

Stack Overflow用户

发布于 2017-08-12 19:20:48

  • 一、多、模型的差异

实际上,您可以使用包含多个记录的@api.one方法调用RecordSet方法。唯一的区别是,对于@api.one,记录的循环将在您定义的函数之外执行,并且作为self,装饰器将一个接一个地传递RecordSet中的每个记录。

作为一个示例,让我们在模型example.model中定义两个函数

代码语言:javascript
复制
@api.one
def print_self_one(self):
    print self

@api.multi
def print_self_multi(self):
    print self

让我们从odoo壳用下面的方式来称呼它们

代码语言:javascript
复制
model = env['example.model']
record_set = model.browse(1,2)
print "record set: " + record_set
print "using @api.one:"
record_set.print_self_one()
print "using @api.multi:"
record_set.print_self_multi()

将返回:

代码语言:javascript
复制
record set: example.model(1,2)
using @api.one:
example.model(1)
example.model(2)
using @api.multi:
example.model(1,2)

因此,以下两者是等价的:

代码语言:javascript
复制
@api.one
_compute_name(self):
    self.name = "Default Name"

@api.multi
print_self_multi(self):
    for record in self:
        record.name = "Default Name"

即使在记录集中有更多的记录被调用。

另一方面,您不使用任何装饰器,则不能使用多(或更少)一个记录来调用它,否则它会抱怨并可能因错误而停止。

@api.model是一个完全不同的故事:只有当您只希望使用空记录集来调用它时,才应该使用这个装饰器。

  • 何时使用哪个

如果您期望一个非空的RecordSet作为输入值,那么,在许多情况下,您可以同时使用@api.one@api.multi,这只是个人偏好的问题。我个人更喜欢在可能的情况下使用@api.one,因为我发现这样的代码要干净得多(另外,对于计算方法和onchange方法,Odoo源代码通常使用@api.one)。

但是,有几种情况只能使用@api.multi

  1. 如果您不仅希望在记录上循环,而且还希望只执行一次: @api.multi print_self_multi(self):打印“这将只打印一次”以便在self中记录:打印“这将打印len(record_set)次数”
  2. 如果返回值很重要。使用@api.one修饰的函数总是返回一个列表(函数中返回值的列表作为迭代)。但是,在许多情况下,特别是在与GUI交互时,您必须返回一个字典(例如,带有警告)。在这些情况下,您必须使用@api.multi
票数 4
EN

Stack Overflow用户

发布于 2015-06-29 10:18:10

api.one

这个装饰器会自动循环到RecordSet记录上。Self被重新定义为当前记录:

代码语言:javascript
复制
@api.one   ## here you will get singleton object in self
def name(self):
    self.name = ’admin’

@api.multi

Self将是不需要迭代的当前RecordSet。这是默认行为:

代码语言:javascript
复制
@api.multi  ## here you will get multi objects in self
def name(self):
    print len(self)
    for obj in self:
        obj.name = 'Admin'

@api.model

这个装饰器将把旧的API调用转换为新的API签名。它允许在迁移代码时保持礼貌。

代码语言:javascript
复制
@api.model 
def name(self):
    pass

方法装饰器需要根据您的方法需要定义,如果您想从方法返回字典,那么您的方法必须包含@api.multi

参考新API指引

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31112660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档