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

Odoo16向导onchange方法更新one2many字段报TypeError错误求助

问题解决:Odoo16向导onchange给One2many赋值报错TypeError: unhashable type: 'dict'

错误根源分析

  1. 关联字段类型错误:employee.goal.add.line中的wizard_id被定义为Integer类型,但One2many字段的反向关联必须是Many2one类型(指向父模型employee.add.wizard)。Odoo依赖这个Many2one字段维护关联关系,用Integer会导致匹配逻辑失效,引发赋值错误。
  2. One2many赋值格式错误:直接给self.line_ids赋值字典列表不符合Odoo的字段操作规范,必须使用Odoo规定的命令三元组操作关联字段。
  3. 无效的清空操作:self.line_ids = {}是错误的清空方式,会触发类型不匹配错误。
  4. 冗余的wizard_id赋值:onchange阶段向导记录尚未持久化(self.id可能不存在),且Odoo会自动维护One2many与反向Many2one的关联,无需手动指定wizard_id。

修正后的完整代码

from odoo import models, fields, api

class EmployeeAddWizard(models.TransientModel):
    _name = 'employee.add.wizard'

    # 补充缺失的字段定义(根据业务逻辑调整类型)
    challenge_id = fields.Many2one('gamification.challenge', string='Challenge')
    employee_id = fields.Many2many('res.users', string='Employees')
    line_ids = fields.One2many('employee.goal.add.line', 'wizard_id', string="Lines")
    
    @api.onchange('challenge_id', 'employee_id')
    def _onchange_action_goal_add(self):
        # 清空现有行记录(Odoo标准命令)
        self.line_ids = [(5,)]
        if self.challenge_id and self.employee_id:
            goal_records = self.env['gamification.challenge.line'].search([('challenge_id', '=', self.challenge_id.id)])
            line_commands = []
            for emp in self.employee_id:
                for line in goal_records:
                    # 构造创建子记录的标准命令
                    line_commands.append((0, 0, {
                        'goal_definition_id': line.definition_id.id,
                        'goal_rating': 0.0,
                        'goal_target': line.target_goal,
                        'employee_id': emp.id,
                    }))
            # 批量赋值给One2many字段
            self.line_ids = line_commands
            
class GoalLine(models.Model):
    _name = 'employee.goal.add.line'

    # 修正为Many2one类型,关联向导模型
    wizard_id = fields.Many2one('employee.add.wizard', string='Wizard', required=True, ondelete="cascade")
    goal_definition_id = fields.Many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade")
    goal_rating = fields.Float('Rating', required=True)
    goal_target = fields.Float('Target Value ', required=True)
    employee_id = fields.Many2one('res.users', string="Employee", required=True, ondelete="cascade")

关键修正点说明

  • 反向关联字段修正:将GoalLine中的wizard_id改为Many2one类型,指向向导模型,确保One2many关联关系正常。
  • 使用Odoo标准命令:
    • (5,):清空所有现有子记录
    • (0, 0, data_dict):创建新的子记录,这是Odoo操作关联字段的标准格式
  • 移除冗余赋值:删除手动设置wizard_id的代码,由Odoo自动维护关联。

内容的提问来源于stack exchange,提问作者Pawan Kumar Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:50:26