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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 02:05:57