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
相关产品推荐
相关产品推荐

