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通过|表示逻辑或,实现了需求的两个过滤条件:
('member_ids.department_id', '=', budget_id.department_id):GLCode关联的TeamMember所属部门与父Budget的部门一致('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
相关产品推荐
相关产品推荐

