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

ValueError: Expected singleton报错 求解Odoo daily.attendance.line考勤代码问题

Odoo考勤模块Expected singleton报错分析与修复方案

ValueError: Expected singleton: daily.attendance.line(123,124,125)

报错核心原因

Odoo的Expected singleton错误本质是操作包含多条记录的记录集时,调用了仅单条记录支持的属性/方法:系统预期当前记录集只有1条数据,但实际拿到了3条(id为123、124、125)。结合给出的代码,问题出在三个位置:

  • _date_test_unique约束逻辑有漏洞:搜索同日期记录时没有排除当前正在校验的记录本身,批量创建多条同日期考勤记录时,search_count会统计所有同日期记录,同时如果未正确遍历记录集,会触发singleton校验。
  • onchange_department方法未做遍历处理:直接调用self.user_id、self.update,当self是多条记录集时,操作会触发singleton错误;且方法末尾返回reload强制刷新动作,会打断onchange前端渲染逻辑,导致关联的daily.attendance.line多条记录被误判为单条处理。
  • create方法未补全:没有返回父类创建后的记录,会导致后续流程拿到空值或异常记录集,也可能触发该错误。

修复方案

1. 修复_date_test_unique约束逻辑

@api.constrains('date')
def _date_test_unique(self):
     for rec in self:
        # 搜索时排除当前记录本身,避免批量创建时误判
        if self.search_count([('date', '=', rec.date), ('id', '!=', rec.id)]) > 0:
            raise ValidationError(_('Current Date Attendance Already Existed!'))

2. 修复onchange_department方法

# datetime导入统一放在文件顶部,不要写在方法内部
from datetime import datetime

@api.onchange('user_id')
def onchange_department(self):
    # 遍历self记录集,兼容多条记录操作
    for rec in self:
        if rec.user_id:
            emps = self.env['hr.employee'].search([])
            emp_attd = []
            now = datetime.now()
            check_in_from = now.strftime('%Y-%m-%d 05:30')
            check_out_from = now.strftime('%Y-%m-%d 14:30')
            for emp in emps:
                vals = {
                    'employe_id': emp.id,
                    'check_in': check_in_from,
                    'check_out': check_out_from,
                    'is_present': True
                }
                emp_attd.append([0, 0, vals])
            rec.employee_ids = emp_attd
        else:
            rec.employee_ids = False
    # 删除reload返回值,onchange无需强制刷新页面,避免打断前端逻辑

3. 补全create方法逻辑

@api.model
def create(self, vals):
    curr = datetime.now()
    new_date = datetime.strftime(curr, '%Y-%m-%d')
    cal_obj = self.env['daily.attendance'].search([])
    # 此处补充你自己的业务逻辑
    # 必须调用父类create方法,返回创建完成的记录对象
    res = super().create(vals)
    return res

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:54:03