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

Odoo中如何将主模型One2many页签字段传递至另一模型页面

Odoo 实现主模型One2many字段复制到目标模型的方案

核心思路

通过自定义按钮触发创建目标记录,同时批量复制主模型笔记本页签内的One2many行数据;或在目标模型的create方法中通过上下文获取主模型记录,自动完成数据填充。


方案一:主模型按钮触发(推荐,更灵活)

1. 主模型代码(含按钮方法)

from odoo import models, fields, api

class MainModel(models.Model):
    _name = 'main.model'
    _description = '主模型'

    name = fields.Char('名称')
    # 笔记本页签内的One2many字段
    one2many_lines = fields.One2many('main.line', 'main_id', '明细行')

    def action_create_target_record(self):
        # 1. 创建目标模型主记录
        target_record = self.env['target.model'].create({
            'name': f"{self.name} - 副本",
            'main_id': self.id,  # 关联主模型记录(可选,便于追溯)
        })

        # 2. 批量复制One2many明细行
        line_vals_list = []
        for line in self.one2many_lines:
            line_vals_list.append({
                'target_id': target_record.id,
                'product_id': line.product_id.id,
                'quantity': line.quantity,
                # 按需添加其他需要复制的字段,如金额、备注等
            })
        
        if line_vals_list:
            self.env['target.line'].create(line_vals_list)

        # 3. 打开目标模型表单页面
        return {
            'type': 'ir.actions.act_window',
            'name': '目标记录详情',
            'res_model': 'target.model',
            'res_id': target_record.id,
            'view_mode': 'form',
            'target': 'current',
        }

2. 目标模型及明细行代码

class TargetModel(models.Model):
    _name = 'target.model'
    _description = '目标模型'

    name = fields.Char('名称')
    main_id = fields.Many2one('main.model', '关联主记录')
    target_lines = fields.One2many('target.line', 'target_id', '目标明细行')

class TargetLine(models.Model):
    _name = 'target.line'
    _description = '目标模型明细行'

    target_id = fields.Many2one('target.model', '关联目标记录')
    product_id = fields.Many2one('product.product', '产品')
    quantity = fields.Float('数量')
    # 与主模型明细行匹配的其他字段

3. 主模型视图添加按钮

在主模型的表单视图中,为笔记本页签或顶部添加触发按钮:

<button name="action_create_target_record" string="创建目标记录" type="object" class="btn-primary"/>

方案二:目标模型create方法自动填充

如果需要在创建目标记录时自动从主模型拉取数据,可通过上下文传递主模型ID,重写create方法实现:

class TargetModel(models.Model):
    _name = 'target.model'
    _description = '目标模型'

    name = fields.Char('名称')
    main_id = fields.Many2one('main.model', '关联主记录')
    target_lines = fields.One2many('target.line', 'target_id', '目标明细行')

    @api.model
    def create(self, vals):
        record = super(TargetModel, self).create(vals)
        # 从上下文获取主模型ID
        main_record_id = self.env.context.get('main_record_id')
        if main_record_id:
            main_record = self.env['main.model'].browse(main_record_id)
            # 复制明细行逻辑同方案一
            line_vals_list = []
            for line in main_record.one2many_lines:
                line_vals_list.append({
                    'target_id': record.id,
                    'product_id': line.product_id.id,
                    'quantity': line.quantity,
                })
            if line_vals_list:
                self.env['target.line'].create(line_vals_list)
        return record

触发时通过上下文传递主模型ID:

# 主模型内的触发方法
def action_open_target_form(self):
    return {
        'type': 'ir.actions.act_window',
        'name': '新建目标记录',
        'res_model': 'target.model',
        'view_mode': 'form',
        'target': 'new',
        'context': {
            'default_main_id': self.id,
            'main_record_id': self.id
        },
    }

注意事项

  • 确保主模型与目标模型的明细行字段结构匹配(数据类型、必填项一致),避免创建失败。
  • 如果明细行包含嵌套的One2many字段,需递归复制子层级数据。
  • 验证当前用户对目标模型及明细行模型的创建权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:40:33