Odoo v15:抽象模型与普通模型One2Many关联(Reference作为inverse_name)故障
解决One2Many与Reference反向关联失效的问题
问题本质
Odoo的One2Many字段默认依赖具体模型的Many2One字段自动维护关联关系,但你用的反向字段是Reference类型——这种字段是动态关联任意模型的,框架没法自动识别并同步One2Many的关联记录,得手动补逻辑解决这个缺口。
具体解决步骤
1. 在抽象模型中重写create/write方法,手动同步关联
在DiscountLineMixin里重写创建和写入逻辑,当通过One2Many字段创建discountlist.percent记录时,手动给order_line_id设置正确的引用值,确保双向关联能对上。
代码示例(DiscountLineMixin):
from odoo import models, fields, api class DiscountLineMixin(models.AbstractModel): _name = 'discount.line.mixin' _description = 'Discount Line Mixin' product_discountlist_ids = fields.One2many( 'discountlist.percent', 'order_line_id', string='Product Discounts' ) @api.model def create(self, vals): record = super().create(vals) # 补全One2Many子记录的Reference字段 if vals.get('product_discountlist_ids'): for line in record.product_discountlist_ids: line.write({'order_line_id': f'{record._model}.{record.id}'}) return record def write(self, vals): res = super().write(vals) # 处理One2Many的新增/修改操作 if vals.get('product_discountlist_ids'): for cmd in vals['product_discountlist_ids']: if cmd[0] == 0: # 新增的子记录 line = self.env['discountlist.percent'].browse(cmd[1]['id']) line.write({'order_line_id': f'{self._model}.{self.id}'}) elif cmd[0] == 1: # 修改的子记录 line = self.env['discountlist.percent'].browse(cmd[1]) line.write({'order_line_id': f'{self._model}.{self.id}'}) return res
2. 在discountlist.percent模型中添加反向同步逻辑
当order_line_id字段变更时,确保对应的宿主模型(继承DiscountLineMixin的模型)的product_discountlist_ids同步更新,避免关联丢失。
代码示例(discountlist.percent):
class DiscountlistPercent(models.Model): _name = 'discountlist.percent' _description = 'Discount List Percent' order_line_id = fields.Reference( selection='_get_reference_selection', string='Order Line Reference' ) # 其他业务字段自行补充 @api.model def _get_reference_selection(self): # 动态获取所有继承DiscountLineMixin的模型,生成Reference可选列表 mixin_models = self.env['ir.model'].search([ ('model', 'in', self.env['discount.line.mixin']._inherit_children) ]) return [(model.model, model.name) for model in mixin_models] @api.onchange('order_line_id') def _onchange_order_line_id(self): if self.order_line_id: # 确保当前记录在宿主模型的One2Many字段中 if self not in self.order_line_id.product_discountlist_ids: self.order_line_id.write({'product_discountlist_ids': [(4, self.id)]}) def write(self, vals): res = super().write(vals) if 'order_line_id' in vals and self.order_line_id: # 同步宿主模型的One2Many字段 if self not in self.order_line_id.product_discountlist_ids: self.order_line_id.write({'product_discountlist_ids': [(4, self.id)]}) return res
3. 调试验证要点
- 创建宿主模型记录后,检查
discountlist.percent的order_line_id是否为模型标识符.记录ID格式(比如sale.order.line.123) - 确认宿主模型的
product_discountlist_ids是否通过(4, id)命令添加了关联记录 - 批量创建场景下,要保证每个子记录的Reference字段都被正确设置
关键注意事项
- Reference字段必须严格遵循
模型标识符.记录ID的格式,Odoo才能正确解析关联 - 利用
_inherit_children属性可以动态获取所有继承抽象模型的具体模型,避免硬写Reference的可选列表 - 不要给One2Many字段添加
auto_join=True,Reference字段不支持自动连接查询
内容的提问来源于stack exchange,提问作者LukaszK
相关产品推荐
相关产品推荐

