预期单例 odoo 9

Expected singleton odoo 9

在树视图中输入 2 个或更多新行并单击保存后出现错误

  raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: my.model(2116, 2117)

我的源代码:

@api.depends('start', 'finish','stop')
def total_fun(self): 
    time1 = datetime.strptime(self.start, "%Y-%m-%d %H:%M:%S")
    time2 = datetime.strptime(self.finish, "%Y-%m-%d %H:%M:%S")
    self.total = round(((time2 - time1).seconds / float(60*60) - self.stop))

错误消息显示 -> expected singleton 这意味着:您正在使用记录集而不是记录。

解决这个问题

for rec in self:

在函数的开头,然后使用rec代替self

正如您在错误信息中看到的那样Expected singleton: my.model(2116, 2117)

默认情况下,在 odoo 中,self 始终是一个记录集(意味着它可以包含不止一个记录。)所以当你这样做时 self.getSomeField 这里 odoo 会混淆你想要从中获取值的记录。

如果您不告诉 odoo 确保当您访问属性时 self 将始终包含一条记录,如果 recordSet 包含多个记录,则会引发此错误。

现在如何告诉 odoo 确保总是有一条记录是通过向方法添加 @api.one 装饰器。但不推荐,因为在你的情况下 odoo 有两条记录,所以他将循环并为每条记录调用方法并传递只有该记录的 recordSet。假设您执行搜索或与数据库进行任何通信。

所以不要使用 @api.one 仅当您确定自己在做什么时,因为您可以进行 10000 次方法调用并与数据库交互。

喜欢这个例子使用@api.one:

   # every call to this method you will execute a search.
   self.env['some.model'].search([('m2o_id' , '=', self.id)]

你可以在循环之前这样做:

  # one query for all record with one call to the method
  result = self.env['some.model'].search([('m2o_id' , 'in', self.ids)]
  for rec in self:
      # use result here 
  # or here ..