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

如何在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)

核心修改说明

  1. 初始化Domain:提前定义空的Domain,确保用户清空requirement_id时,子表的panel_id不再被过滤
  2. 批量收集ID:使用Odoo内置的mapped方法一次性提取所有符合条件的panel_user_id.id,替代低效的循环遍历
  3. 批量匹配条件:将原有的单个ID匹配(=)改为批量匹配(in),确保所有符合条件的评审员都能被筛选出来
  4. 移除循环内return:保证所有时段记录都被处理,不会提前终止函数

内容的提问来源于stack exchange,提问作者Mahfujul Hasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:15:55