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

Odoo点击按钮实现one2many字段产品跨模型展示到另一one2many字段

Odoo 跨模型One2many字段数据同步实现方案

现有代码核心问题

  • product_line_ids字段定义非法:related='line_ids.product_id'指向的是product.product模型的记录集,不是One2many类型字段,既不支持存储,也无法按行读取采购行数据。
  • 赋值目标错误:方法逻辑中始终在给当前审批模型自身的字段赋值,没有操作目标purchase.requisition模型的对应字段,无法实现跨模型数据写入。
  • 行值构造规则错误:One2many写入的(0,0, vals)语法要求vals必须是子表模型的合法字段键值对,直接传入line.line_ids既没有匹配子表字段要求,也没有填写必填字段,无法正常落库。
  • 缺少模型关联依据:代码中没有定义审批单和目标采购协议的关联关系,无法定位数据要写入的具体采购协议记录。

正确实现步骤

  1. 修正模型字段定义
    移除错误定义的product_line_ids字段,新增审批单到目标采购协议的Many2one关联字段,用于定位写入目标,代码参考:

    from odoo import models, api, fields
    
    class Approval(models.Model):
        _inherit = "approval.request"
        # 新增关联目标采购协议的字段,用于指定数据写入对象
        target_requisition_id = fields.Many2one('purchase.requisition', string='目标采购协议')
        # 原有line_ids字段如果已经在父模型定义,不要重复定义避免覆盖原有逻辑
    

    空的PurchaseReq继承类如果没有定制需求可以直接删除,不需要保留冗余代码。

  2. 修正按钮触发的写入逻辑
    遍历源One2many的采购行数据,构造符合目标子表字段要求的值列表,写入到目标采购协议的对应One2many字段,代码参考:

    def purchase_agreement(self):
        for rec in self:
            # 基础校验
            if not rec.target_requisition_id:
                raise models.ValidationError('请先选择要同步数据的目标采购协议')
            sync_line_list = []
            # 遍历源采购行数据
            for source_line in rec.line_ids:
                # 按purchase.requisition.line模型的字段要求构造行值,以下为通用字段示例,需根据本地实际字段调整
                line_vals = {
                    'product_id': source_line.product_id.id,
                    'product_qty': source_line.product_qty,
                    'price_unit': source_line.price_unit,
                    'name': source_line.name,
                    'product_uom_id': source_line.product_uom_id.id,
                }
                sync_line_list.append((0, 0, line_vals))
            # 写入目标采购协议的One2many字段,字段名需和本地purchase.requisition模型的行字段名保持一致
            rec.target_requisition_id.write({
                'line_ids': sync_line_list
            })
            # 可选:写入完成后跳转到目标采购协议表单页
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'purchase.requisition',
                'res_id': rec.target_requisition_id.id,
                'view_mode': 'form',
                'target': 'current'
            }
    

注意事项

  • 如果业务需求不是复制新行,而是要把现有采购行直接转移到目标采购协议,不要使用(0,0)创建新行的语法,改用(4, 源行id)语法即可,但该操作会修改源行的关联外键,导致原采购申请下的该行数据消失,非必要不要使用。
  • 构造行值时必须补全子表的所有必填字段,否则会触发数据库非空约束报错。
  • 非必要不要在related字段上执行写入操作,多数related字段默认只读,强行写入容易触发链路关联报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:09:19