Odoo13 父字段onchange联动过滤子表关联字段不生效问题
问题根因
- 代码逻辑错误:onchange方法内对self做循环时直接return,仅会处理第一条遍历到的记录就终止执行,批量操作场景完全失效,单记录场景下也不符合Odoo onchange的返回规范。
- 机制适配问题:仅靠主表onchange返回嵌套明细字段的domain,在Odoo13的前端表单渲染逻辑中无法覆盖存量数据加载场景,打开已保存的单据时,明细行的budget_line字段不会应用过滤规则。
- 边界值缺失:未处理budget_id为空的场景,未选预算时domain规则异常,会导致明细行可选范围不符合预期。
- 细节笔误:字段
budget_id的显示名拼写错误(Project Bugdet应为Project Budget),该问题不影响核心功能但属于不规范实现。
正确实现代码
实现逻辑同时覆盖两种场景:一是选中/切换预算时通过onchange实时更新明细行可选域,二是在明细行字段上定义关联主表的动态domain,保证打开历史单据时过滤规则依然生效。
from odoo import models, fields, api class AccountMove(models.Model): _inherit = 'account.move' budget_id = fields.Many2one('project.budget', string='Project Budget') @api.onchange('budget_id') def _onchange_budget_id_filter_budget_line(self): # 初始化空domain,未选预算时默认不做过滤(可按需调整为返回空列表不显示任何行) line_domain = [] valid_budget_line_ids = [] if self.budget_id: valid_budget_line_ids = self.budget_id.budget_line_ids.ids line_domain = [('id', 'in', valid_budget_line_ids)] # 可选逻辑:切换预算时自动清空明细中不属于当前预算的已选值 for line in self.invoice_line_ids: if line.budget_line and line.budget_line.id not in valid_budget_line_ids: line.budget_line = False else: # 可选逻辑:未选预算时清空所有明细的预算行选择 self.invoice_line_ids.update({'budget_line': False}) return { 'domain': { 'invoice_line_ids.budget_line': line_domain } } class AccountMoveLine(models.Model): _inherit = 'account.move.line' budget_line = fields.Many2one( 'project.budget.line', string='Budget Line', # 字段级动态domain,覆盖表单加载场景的过滤逻辑 domain=lambda self: [ ('id', 'in', self.move_id.budget_id.budget_line_ids.ids) ] if self.move_id.budget_id else [] )
部署注意事项
- 代码更新后需要重启Odoo服务,升级对应自定义模块
- 清理浏览器缓存,避免前端加载旧的表单JS逻辑导致规则不生效
- 如果你自定义过account.move的明细关联字段(Odoo13默认是
invoice_line_ids),需要将代码中对应字段名替换为你实际使用的字段名
内容的提问来源于stack exchange,提问作者SH EB
相关产品推荐
相关产品推荐

