@api.one、@api.multi 和@api.model 有什么区别?
What is difference between @api.one, @api.multi and @api.model?
我对 Odoo 中的 @api.one
、@api.multi
和 @api.model
感到困惑。
这三者有什么区别,它们的用例是什么?
api.one
此装饰器会自动为您在 RecordSet 的 Records 上循环。自己被重新定义为当前记录:
@api.one ## here you will get singleton object in self
def name(self):
self.name = ’admin’
@api.multi
Self 将是没有迭代的当前 RecordSet。这是默认行为:
@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 签名。允许在迁移代码时保持礼貌。
@api.model
def name(self):
pass
方法装饰器需要根据你的方法需要定义,如果你想从方法中 return 字典那么你的方法必须包含 @api.multi
.
api.one
用于仅在一条记录上调用方法时使用。它确保在使用 api.one
装饰器调用方法时没有多个记录。假设您获得了记录 partner = res.partner(1,)
。它只有一条记录,并且有方法例如(在res.partner
):
@api.one
def get_name(self):
return self.name #self here means one record
像这样调用它有效:
partner.get_name()
但是如果有更多的记录,比如partners = res.partner(1, 2,)
调用它会发出警告,告诉您只能在一条记录上调用它。对于多条记录,使用 api.multi
,其中 self
是记录集,它可以遍历所有记录来做某事。例如:
@api.multi
def get_partner_names(self):
names = []
for rec in self:
names.append(rec.name)
return ', '.join(names)
而 api.model
被认为是在您需要对模型本身做某事而不需要 modify/check 某些确切模型的 record/records 时使用。例如,可能有 return 一些关于模型结构的元信息或一些辅助方法等的方法。同样在文档中,据说这个 api 在从旧的 [=40] 迁移时很好用=],因为它 "politely" 将代码转换为新的 api。同样根据我自己的经验,如果您需要 return 某些东西的方法,model
装饰器对它很有用。 api.one
return 是一个空列表,因此在应该 return 某些东西的方法上使用 api.one
时可能会导致意外行为。
更多信息:http://odoo-new-api-guide-line.readthedocs.org/en/latest/decorator.html
- one、multi和model的区别
您实际上可以 调用包含多个记录的 RecordSet 的 @api.one
方法。唯一的区别是 @api.one
记录的循环将在您定义的函数之外完成,而 self
装饰器将一条一条地传递 RecordSet 中的每条记录。
例如,让我们在模型中定义两个函数 example.model
:
@api.one
def print_self_one(self):
print self
@api.multi
def print_self_multi(self):
print self
让我们从 odoo shell 中按以下方式称呼它们:
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()
会 return:
record set: example.model(1,2)
using @api.one:
example.model(1)
example.model(2)
using @api.multi:
example.model(1,2)
因此,下面两个是等价的:
@api.one
_compute_name(self):
self.name = "Default Name"
@api.multi
print_self_multi(self):
for record in self:
record.name = "Default Name"
即使在记录集中使用更多记录调用他们。
另一方面,你不使用 any 装饰器,那么它不能被调用多于(或少于)一条记录,否则它会抱怨并可能停止出现错误。
@api.model
是一个完全不同的故事:只有当您只希望用空记录集调用它时,才应该使用这个装饰器。
- 什么时候用哪个
如果你期望一个非空的RecordSet作为输入值,那么在很多情况下,你可以同时使用@api.one
和@api.multi
,这只是个人喜好的问题。我个人更喜欢在可能的情况下使用 @api.one
,因为我发现这样代码更清晰(另外,对于计算和 onchange 方法,Odoo 源通常使用 @api.one
)。
但在某些情况下您只能使用 @api.multi
:
如果您不仅想循环记录,还想只做一次:
@api.multi
print_self_multi(self):
print "this will only be printed once"
for record in self:
print "this will be printed len(record_set) times"
如果 return 值很重要。用 @api.one
装饰的函数将 总是 return 一个列表(函数中 return 值的列表作为迭代)。但在许多情况下,尤其是在与 GUI 交互时,您将不得不 return 字典(例如带有警告)。在这些情况下,您将不得不使用 @api.multi
.
@api.multi
装饰一个记录式方法,其中 self
是一个记录集。该方法通常定义对记录的操作。这样的方法::
@api.multi
def method(self, args):
...
可以在记录和传统风格中调用,如::
recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, ids, args, context=context)
@api.model
装饰一个记录式方法,其中 self
是一个记录集,但它的内容不相关,只有模型是相关的。这样的方法::
@api.model
def method(self, args):
...
可以在记录和传统风格中调用,如::
recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, args, context=context)
您可以在文件中找到这些装饰器的基本代码:
odoo/api.py
我对 Odoo 中的 @api.one
、@api.multi
和 @api.model
感到困惑。
这三者有什么区别,它们的用例是什么?
api.one
此装饰器会自动为您在 RecordSet 的 Records 上循环。自己被重新定义为当前记录:
@api.one ## here you will get singleton object in self
def name(self):
self.name = ’admin’
@api.multi
Self 将是没有迭代的当前 RecordSet。这是默认行为:
@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 签名。允许在迁移代码时保持礼貌。
@api.model
def name(self):
pass
方法装饰器需要根据你的方法需要定义,如果你想从方法中 return 字典那么你的方法必须包含 @api.multi
.
api.one
用于仅在一条记录上调用方法时使用。它确保在使用 api.one
装饰器调用方法时没有多个记录。假设您获得了记录 partner = res.partner(1,)
。它只有一条记录,并且有方法例如(在res.partner
):
@api.one
def get_name(self):
return self.name #self here means one record
像这样调用它有效:
partner.get_name()
但是如果有更多的记录,比如partners = res.partner(1, 2,)
调用它会发出警告,告诉您只能在一条记录上调用它。对于多条记录,使用 api.multi
,其中 self
是记录集,它可以遍历所有记录来做某事。例如:
@api.multi
def get_partner_names(self):
names = []
for rec in self:
names.append(rec.name)
return ', '.join(names)
而 api.model
被认为是在您需要对模型本身做某事而不需要 modify/check 某些确切模型的 record/records 时使用。例如,可能有 return 一些关于模型结构的元信息或一些辅助方法等的方法。同样在文档中,据说这个 api 在从旧的 [=40] 迁移时很好用=],因为它 "politely" 将代码转换为新的 api。同样根据我自己的经验,如果您需要 return 某些东西的方法,model
装饰器对它很有用。 api.one
return 是一个空列表,因此在应该 return 某些东西的方法上使用 api.one
时可能会导致意外行为。
更多信息:http://odoo-new-api-guide-line.readthedocs.org/en/latest/decorator.html
- one、multi和model的区别
您实际上可以 调用包含多个记录的 RecordSet 的 @api.one
方法。唯一的区别是 @api.one
记录的循环将在您定义的函数之外完成,而 self
装饰器将一条一条地传递 RecordSet 中的每条记录。
例如,让我们在模型中定义两个函数 example.model
:
@api.one
def print_self_one(self):
print self
@api.multi
def print_self_multi(self):
print self
让我们从 odoo shell 中按以下方式称呼它们:
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()
会 return:
record set: example.model(1,2)
using @api.one:
example.model(1)
example.model(2)
using @api.multi:
example.model(1,2)
因此,下面两个是等价的:
@api.one
_compute_name(self):
self.name = "Default Name"
@api.multi
print_self_multi(self):
for record in self:
record.name = "Default Name"
即使在记录集中使用更多记录调用他们。
另一方面,你不使用 any 装饰器,那么它不能被调用多于(或少于)一条记录,否则它会抱怨并可能停止出现错误。
@api.model
是一个完全不同的故事:只有当您只希望用空记录集调用它时,才应该使用这个装饰器。
- 什么时候用哪个
如果你期望一个非空的RecordSet作为输入值,那么在很多情况下,你可以同时使用@api.one
和@api.multi
,这只是个人喜好的问题。我个人更喜欢在可能的情况下使用 @api.one
,因为我发现这样代码更清晰(另外,对于计算和 onchange 方法,Odoo 源通常使用 @api.one
)。
但在某些情况下您只能使用 @api.multi
:
如果您不仅想循环记录,还想只做一次:
@api.multi print_self_multi(self): print "this will only be printed once" for record in self: print "this will be printed len(record_set) times"
如果 return 值很重要。用
@api.one
装饰的函数将 总是 return 一个列表(函数中 return 值的列表作为迭代)。但在许多情况下,尤其是在与 GUI 交互时,您将不得不 return 字典(例如带有警告)。在这些情况下,您将不得不使用@api.multi
.
@api.multi
装饰一个记录式方法,其中 self
是一个记录集。该方法通常定义对记录的操作。这样的方法::
@api.multi
def method(self, args):
...
可以在记录和传统风格中调用,如::
recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, ids, args, context=context)
@api.model
装饰一个记录式方法,其中 self
是一个记录集,但它的内容不相关,只有模型是相关的。这样的方法::
@api.model
def method(self, args):
...
可以在记录和传统风格中调用,如::
recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, args, context=context)
您可以在文件中找到这些装饰器的基本代码: odoo/api.py