Odoo17中One2many字段删除记录保存后重现问题求助
Odoo 17多One2many字段删除记录后恢复的解决办法
问题根源
你遇到的问题核心是:同一个elections.member模型被三个One2many字段关联,Odoo默认对One2many的删除操作是解除关联(仅把member的election_id设为空),但多个One2many字段的存在会导致Odoo在刷新记录集时,误将未彻底移除的记录重新加载回列表;另外字段定义和视图的domain不一致,也可能让符合条件的记录再次显示。
解决方案
方案1:修改One2many字段的删除行为(物理删除)
如果业务允许直接删除elections.member记录,在One2many字段定义中添加ondelete='cascade',这样删除列表中的记录时会直接物理删除该member,彻底避免恢复:
member_ids = fields.One2many('elections.member', 'election_id', string='Members', domain=[('is_observer','=', False )], ondelete='cascade') observer_ids=fields.One2many('elections.member', 'election_id',string='Observers', domain=[('is_observer','=', True ), ('is_candidate','=', False )], ondelete='cascade') all_member_ids=fields.One2many('elections.member', 'election_id',string='All members (including observers and candidates)', ondelete='cascade')
方案2:改用计算字段分组(推荐,避免多One2many冲突)
保留一个实际存储关联的One2many字段,另外两个分组用计算字段实现,从根源上避免多One2many的记录集混淆:
模型代码修改:
# 仅保留一个实际存储关联的字段 all_member_ids = fields.One2many('elections.member', 'election_id', string='All members') # 计算字段实现成员分组 member_ids = fields.One2many('elections.member', compute='_compute_member_ids', inverse='_inverse_member_ids', string='Members') observer_ids = fields.One2many('elections.member', compute='_compute_observer_ids', inverse='_inverse_observer_ids', string='Observers') def _compute_member_ids(self): for rec in self: # 过滤出非观察者、非候选人的成员 rec.member_ids = rec.all_member_ids.filtered(lambda m: not m.is_observer and not m.is_candidate) def _inverse_member_ids(self): for rec in self: # 处理新增记录:自动设置属性并关联当前选举 for member in rec.member_ids: member.is_observer = False member.is_candidate = False member.election_id = rec.id # 处理删除记录:解除关联 removed_members = rec.all_member_ids - rec.member_ids for member in removed_members.filtered(lambda m: not m.is_observer and not m.is_candidate): member.election_id = False def _compute_observer_ids(self): for rec in self: # 过滤出观察者、非候选人的成员 rec.observer_ids = rec.all_member_ids.filtered(lambda m: m.is_observer and not m.is_candidate) def _inverse_observer_ids(self): for rec in self: # 处理新增记录:自动设置属性并关联当前选举 for member in rec.observer_ids: member.is_observer = True member.is_candidate = False member.election_id = rec.id # 处理删除记录:解除关联 removed_members = rec.all_member_ids - rec.observer_ids for member in removed_members.filtered(lambda m: m.is_observer and not m.is_candidate): member.election_id = False
视图代码无需修改
原来的视图中member_ids和observer_ids的配置可以直接保留,计算字段会自动处理数据的显示和编辑逻辑。
方案3:统一字段与视图的Domain
确保字段定义的domain和视图中的domain完全一致,避免Odoo刷新时加载不符合视图过滤条件但符合字段定义的记录:
比如member_ids字段定义的domain加上('is_candidate','=', False ),和视图保持一致:
member_ids = fields.One2many('elections.member', 'election_id', string='Members', domain=[('is_observer','=', False ), ('is_candidate','=', False )])
内容的提问来源于stack exchange,提问作者Ernesto Ruiz
相关产品推荐
相关产品推荐

