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

Odoo@onchange监听任务阶段变更创建活动时报NewId对象不可迭代错误求助

问题原因

TypeError: 'NewId' object is not iterable报错的核心是@api.onchange的运行机制不匹配当前需求:

  • Odoo触发@api.onchange时,会生成仅存在于内存的临时记录对象,用特殊的NewId类型替代真实的数据库主键ID,此时代码中调用的self._origin.id本质是NewId对象而非整数,传入mail.activity要求为整数类型的res_id字段就会触发类型错误。
  • 从设计层面看,@api.onchange仅用于前端编辑时的字段预赋值,不应该执行创建活动这类写入数据库的持久化操作,onchange触发时记录可能还未保存到数据库,关联逻辑必然存在隐患。
修正方案

将监听阶段变更的逻辑从重写@api.onchange改为重写write方法,该方法会在记录实际提交到数据库后触发,所有记录ID都是真实有效的整数值:

from datetime import datetime, timedelta
from odoo import api, fields, models

class ProjectSetAndDateType(models.Model):
    _inherit = 'project.task.type'

    last_stage = fields.Boolean(string="Fertigstellungsstufe")


class ProjectSetEndDate(models.Model):
    _inherit = 'project.task'

    def write(self, vals):
        res = super().write(vals)
        # 仅当stage_id被修改时触发逻辑
        if 'stage_id' in vals:
            for task in self:
                if task.stage_id.last_stage:
                    # 赋值完成状态和结束时间
                    task.write({
                        'kanban_state': "done",
                        'date_finished': datetime.now()
                    })
                    # 创建归档提醒活动
                    activity_deadline = datetime.now() + timedelta(days=30)
                    data = {
                        'res_id':  task.id,
                        'res_model': 'project.task',
                        'res_model_id': self.env['ir.model']._get_id('project.task'),
                        'user_id': task.project_id.user_id.id,
                        'summary': 'Aufgabe archivieren nach Fertigstellung',
                        'activity_type_id': self.env.ref('project_set_end_date.mail_set_end_date_archive').id,
                        'date_deadline': activity_deadline
                    }
                    self.env['mail.activity'].create(data)
        return res
优化说明
  • 用_get_id方法替代search取模型ID,性能更优,写法更简洁
  • 新增批量处理逻辑,兼容同时修改多个任务的场景,避免单条记录报错导致整个操作失败
  • 直接传入datetime对象即可,不需要手动转字符串,Odoo ORM会自动处理时区和格式转换
  • 移除了_origin的调用,此时记录已经保存到数据库,直接取当前对象的属性即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:27:04