Odoo14计算年龄与工龄时出现Singleton错误的解决咨询
解决Odoo14中计算员工年龄/工龄触发的ValueError问题
错误原因
报错Expected singleton: restaurant.karyawan(1, 2)的核心问题是:你的计算方法被调用时,self是包含多条员工记录的记录集,但代码里直接通过self.tanggal_lahir或self.mulai_bekerja访问字段——这种写法仅适用于单个记录(singleton),当处理多记录(比如批量操作、列表视图加载)时就会触发异常。
解决方案
修改计算方法,遍历记录集中的每一条记录,单独处理每个员工的字段值,再赋值到对应的计算字段。同时优化日期处理逻辑,避免不必要的类型转换。
修改后的完整代码
from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta from odoo import api, fields, models class RestaurantKaryawan(models.Model): _name = 'restaurant.karyawan' _description = 'Restaurant Employee' tanggal_lahir = fields.Date(string='Tanggal Lahir') usia = fields.Integer(string='Usia', compute='_hitung_usia') mulai_bekerja = fields.Date(string='Mulai Bekerja') lama_bekerja = fields.Char(string='Lama Bekerja', compute='_lama_bekerja') # 计算年龄 @api.depends('tanggal_lahir') def _hitung_usia(self): today = datetime.today().date() for karyawan in self: if karyawan.tanggal_lahir: # 直接使用date字段,无需转字符串再解析 delta = today - karyawan.tanggal_lahir karyawan.usia = delta.days // 365 else: karyawan.usia = 0 # 为空时设置默认值 # 计算工龄 @api.depends('mulai_bekerja') def _lama_bekerja(self): today = datetime.today().date() for karyawan in self: if karyawan.mulai_bekerja: rel_delta = relativedelta(today, karyawan.mulai_bekerja) karyawan.lama_bekerja = f"{rel_delta.years} Tahun {rel_delta.months} Bulan {rel_delta.days} Hari" else: karyawan.lama_bekerja = "-" # 为空时显示占位符
关键修改点
- 新增
for karyawan in self:循环,遍历每个员工记录,确保处理的是单个记录(singleton) - 优化日期处理:直接使用
karyawan.tanggal_lahir(无需转字符串再用strptime解析),如果字段是Date类型,本身就是date对象 - 增加空值处理:当
tanggal_lahir或mulai_bekerja为空时,给计算字段设置合理的默认值,避免逻辑错误
内容的提问来源于stack exchange,提问作者Denny
相关产品推荐
相关产品推荐

