如何在Odoo表单视图中以嵌入表单而非列表展示编辑One2many字段
Odoo 一对一关联模型的表单视图实现方案
问题分析
你当前用One2many + Many2one实现一对一关联,但One2many字段默认以列表形式展示,无法满足单表单内联创建/编辑的需求。需要从模型层加约束确保一对一关系,同时在视图层调整渲染方式。
模型层优化
Model A 修改
添加计算字段实现单记录关联,同时加约束确保最多关联一条Model B:
from odoo import models, fields, api, exceptions class ModelA(models.Model): _name = 'model.a' b_ids = fields.One2many('model.b', 'a_id') # 新增计算字段,用于视图层绑定单条Model B记录 b_id = fields.Many2one('model.b', compute='_compute_b_id', inverse='_inverse_b_id') @api.depends('b_ids') def _compute_b_id(self): for rec in self: # 取第一条关联的B记录(确保最多一条) rec.b_id = rec.b_ids[:1].id def _inverse_b_id(self): for rec in self: if rec.b_id: # 同步关联关系 rec.b_id.a_id = rec.id else: # 删除已关联的B记录 rec.b_ids.unlink() # 约束:每个A最多关联一个B @api.constrains('b_ids') def _check_single_b(self): for rec in self: if len(rec.b_ids) > 1: raise exceptions.ValidationError("每个Model A只能关联一条Model B记录")
Model B 保留(已满足约束)
a_id字段的unique=True已确保一条B只能关联一条A:
class ModelB(models.Model): _name = 'model.b' a_id = fields.Many2one('model.a', unique=True, required=True) # 这里添加Model B的其他业务字段 # field1 = fields.Char(string="字段1") # field2 = fields.Integer(string="字段2")
视图层配置
在Model A的表单视图中,使用form widget渲染b_id字段,实现单表单内联效果:
<record id="model_a_form" model="ir.ui.view"> <field name="name">model.a.form.view</field> <field name="model">model.a</field> <field name="arch" type="xml"> <form> <sheet> <!-- Model A自身字段区域 --> <group> <field name="name"/> <!-- 其他A的字段 --> </group> <!-- 关联Model B的内联表单区域 --> <notebook> <page string="关联信息"> <!-- 用form widget实现单表单内联,支持创建/编辑/删除 --> <field name="b_id" widget="form" options="{'mode': 'edit', 'create': true, 'delete': true}"/> </page> </notebook> </sheet> </form> </field> </record>
效果说明
- 打开Model A的表单时,关联的Model B会以单独嵌入表单展示,而非列表。
- 可直接在该表单区域创建新的Model B记录,或编辑已关联的记录,删除操作会同步解除关联。
- 模型层的约束确保了严格的一对一关系,不会出现多条关联的情况。
内容的提问来源于stack exchange,提问作者ASP
相关产品推荐
相关产品推荐

