如何在One2many字段的onchange函数中添加domain过滤
Odoo One2many子表字段Domain过滤失效修复方案
问题根源
原代码存在三个关键问题导致过滤失效:
- 循环内部直接
return,仅能获取第一条匹配的时段记录,无法收集所有符合条件的评审员ID - Domain条件使用单个ID匹配(
=),而非批量匹配的in操作符 - 未处理
requirement_id清空时的Domain重置逻辑,导致清空后过滤条件仍残留
修复后的代码
完整修正后的模型代码如下:
class PanelVendorAssignment(models.Model): _name = "panel.vendor.assignment" requirement_id = fields.Many2one('hr.job', string='需求') panel_vendor_assignments_ids = fields.One2many( string='供应商', comodel_name='panel.vendor.assignment.line', inverse_name='panel_vendor_assignment_id', tracking=True) @api.onchange('requirement_id') def _onchange_panel_stage(self): # 初始化Domain,确保清空需求时过滤条件重置 domain = {'panel_vendor_assignments_ids.panel_id': []} if self.requirement_id: # 搜索当前需求下状态为"open"的时段记录 panel_stage_ids = self.env['panel.time.slot.availability'].sudo().search( [('requirement_id', '=', self.requirement_id.id), ('status', '=', 'open')]) # 批量提取所有符合条件的评审员ID panel_ids = panel_stage_ids.mapped('panel_user_id.id') # 设置子表panel_id的过滤条件 domain['panel_vendor_assignments_ids.panel_id'] = [('id', 'in', panel_ids)] return {'domain': domain} class PanelVendorAssignmentLine(models.Model): _name = 'panel.vendor.assignment.line' panel_vendor_assignment_id = fields.Many2one(comodel_name='panel.vendor.assignment', ondelete='cascade') panel_id = fields.Many2one(comodel_name='res.partner', string='评审员', required=True)
核心修改说明
- 初始化Domain:提前定义空的Domain,确保用户清空
requirement_id时,子表的panel_id不再被过滤 - 批量收集ID:使用Odoo内置的
mapped方法一次性提取所有符合条件的panel_user_id.id,替代低效的循环遍历 - 批量匹配条件:将原有的单个ID匹配(
=)改为批量匹配(in),确保所有符合条件的评审员都能被筛选出来 - 移除循环内return:保证所有时段记录都被处理,不会提前终止函数
内容的提问来源于stack exchange,提问作者Mahfujul Hasan
相关产品推荐
相关产品推荐

