You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ValueError: Expected singleton报错与Aveant模型代码排查求助

排查Odoo中Aveant模型的ValueError: Expected singleton错误

这个错误在Odoo开发里太常见了,本质就是你试图对一个包含多条记录的集合访问只有单条记录才有的属性(比如.id)。咱们结合你的代码一步步拆解问题:

错误原因

1. 直接访问记录集的单值属性

看这段代码:

attachements=self.env["facturation.attachement"].search([('contrat_id','=',self.contrat_id.id)])
print attachements.id

search()方法返回的是记录集,可能是0条、1条或多条记录。如果当前contrat_id关联了多个facturation.attachement记录,attachements就是一个多记录集合,这时候你直接调用attachements.id就会触发Expected singleton错误——因为.id是单条记录的专属属性,记录集没有这个属性。

2. @api.multi下的self处理

你的方法用了@api.multi装饰器,意味着self可能是多条记录的集合。如果在批量操作场景下触发这个方法,访问self.contrat_id.id也会报错:因为self.contrat_id会变成一个包含多条contrat记录的集合,同样不能直接用.id。

另外,你的travSup_ids是compute字段,但代码里没加@api.depends装饰器,这会导致compute方法无法正确触发,也是潜在问题。

解决思路

1. 处理记录集的访问逻辑

根据你的业务需求,分两种情况处理:

  • 每个合同对应唯一附件:用limit=1确保只取单条记录,同时先判断记录是否存在:
    attachements = self.env["facturation.attachement"].search([('contrat_id','=',self.contrat_id.id)], limit=1)
    if attachements:  # 先检查是否有记录
        print(attachements.id)
        trv = self.env["facturation.travsup"].search([('attachment_id','=',attachements.id)])
    
  • 每个合同对应多个附件:遍历记录集处理每条记录,或者用ids属性获取所有id的列表:
    attachements = self.env["facturation.attachement"].search([('contrat_id','=',self.contrat_id.id)])
    # 遍历每条附件
    for att in attachements:
        print(att.id)
        trv = self.env["facturation.travsup"].search([('attachment_id','=',att.id)])
        # 处理当前附件对应的travsup记录
    
    # 或者一次性获取所有附件对应的travsup
    trv = self.env["facturation.travsup"].search([('attachment_id','in', attachements.ids)])
    

2. 修正方法的装饰器与遍历逻辑

因为是@api.onchange方法,通常针对单条记录,但为了兼容批量场景,建议遍历self中的每条记录:

@api.multi
@api.onchange('contrat_id')
@api.depends('contrat_id')  # compute字段必须加这个,指定依赖字段
def display_trav(self):
    for rec in self:  # 遍历每条Aveant记录
        trav_sups = self.env["facturation.travsup"]
        if rec.contrat_id:
            attachements = self.env["facturation.attachement"].search([('contrat_id','=',rec.contrat_id.id)])
            trav_sups = self.env["facturation.travsup"].search([('attachment_id','in', attachements.ids)])
        rec.travSup_ids = trav_sups  # 给当前记录的One2many字段赋值

3. 处理空记录集的边界情况

不管是附件还是travsup记录,都要先判断是否存在,避免访问空记录集的属性导致错误。比如当没有匹配的附件时,清空traSup_ids字段。

内容的提问来源于stack exchange,提问作者Taha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:10:16