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

Odoo ORM中BudgetLine模型GL Code字段Domain过滤失效如何修复?

问题描述

现有Odoo系统包含Budget、BudgetLine、Department、TeamMember、GLCode五个模型,BudgetLine可从Budget表单页面创建。需求为过滤BudgetLine的gl_code字段,使其满足以下任一条件:

  • 父Budget关联的部门与GLCode关联的TeamMember部门一致
  • GLCode存在于该部门关联TeamMember的gl_codes中

尝试以下domain配置但未生效:

gl_code = fields.Many2one(
    'mn.gl_code', string='GL Code', 
    domain=lambda self: [
        ('id', 'in',  self.budget_id.department_id.team_member_ids.mapped('gl_codes').ids)
    ]
)

相关模型核心代码如下:

class Budget(models.Model):
    _name = 'mn.budget'

    name = fields.Char(string='Name', required=True, tracking=True)
    budget_line_ids = fields.One2many('mn.budget.line', 'budget_id', string='Budget Lines')
    department_id = fields.Many2one('mn.department', string='Department')


class BudgetLine(models.Model):
    _name = 'mn.budget.line'

    budget_id = fields.Many2one('mn.budget', string='Budget')
    gl_code = fields.Many2one('mn.gl_code', string='GL Code')
    team_members = fields.Many2many(related='gl_code.member_ids', string='Team Members')

class Department(models.Model):
    _name = 'mn.department'
    name = fields.Char(string='Name')
    budget_ids = fields.One2many('mn.budget', 'department_id', string='Budgets')
    team_member_ids = fields.One2many('mn.team_member', 'department_id', string='Team Members')

class GLCode(models.Model):
    _name = 'mn.gl_code'

    code = fields.Char(string='GL Code', required=True)
    budget_line_ids = fields.One2many('mn.budget.line', 'gl_code', string='Budget Lines')
    member_ids = fields.Many2many('mn.team_member', string='Team Members')

class TeamMember(models.Model):
    _name = 'mn.team_member'

    member_id = fields.Many2one('res.users', string='Member', domain=[('groups_id', '=', 1)])
    department_id = fields.Many2one('mn.department', string='Department')
    gl_codes = fields.Many2many('mn.gl_code', string='GL Codes')
问题原因

原lambda domain失效的核心原因:

  • 从Budget表单的One2many字段创建BudgetLine时,self是空的BudgetLine记录集(尚未保存到数据库),无法通过self.budget_id获取父Budget的关联数据,导致mapped('gl_codes').ids返回空列表,过滤结果为空。
  • Lambda domain仅在字段初始化时执行一次,无法动态响应父记录的字段变化。
修复方案

使用动态字符串domain,利用Odoo的ORM关联查询能力,直接关联父Budget的部门信息,同时覆盖需求中的两个条件:

gl_code = fields.Many2one(
    'mn.gl_code', string='GL Code',
    domain="[('member_ids.department_id', '=', budget_id.department_id), '|', ('id', 'in', budget_id.department_id.team_member_ids.gl_codes)]"
)

代码解释

该domain通过|表示逻辑或,实现了需求的两个过滤条件:

  1. ('member_ids.department_id', '=', budget_id.department_id):GLCode关联的TeamMember所属部门与父Budget的部门一致
  2. ('id', 'in', budget_id.department_id.team_member_ids.gl_codes):GLCode存在于父Budget部门下所有TeamMember的gl_codes集合中

补充说明

如果需要支持独立创建BudgetLine的场景(不从Budget表单进入),可添加上下文默认值判断避免报错:

gl_code = fields.Many2one(
    'mn.gl_code', string='GL Code',
    domain="[('member_ids.department_id', '=', budget_id.department_id), '|', ('id', 'in', budget_id.department_id.team_member_ids.gl_codes)]",
    context={"default_budget_id": lambda self: self._context.get('default_budget_id')}
)

内容的提问来源于stack exchange,提问作者Riajul Kashem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:52:44