Odoo 14中如何实现四级关联选择字段的动态子集筛选?
Odoo 14 实现四级联动选择字段方案
在Odoo 14里,确实不能再通过on_change方法直接返回domain来筛选字段选项了,下面分两种常见场景给你具体实现方案:
场景一:基于Many2one字段的模型子集联动
如果你的四个选择字段是关联其他业务模型的Many2one字段(比如层级分类这类关联模型),可以这么做:
1. 定义基础字段
先在模型里声明四个Many2one字段,假设关联的层级模型分别是model.level1、model.level2、model.level3、model.level4(注意层级模型间要提前做好关联,比如model.level2里要有level1_id字段关联model.level1):
from odoo import models, fields, api class MyModel(models.Model): _name = 'my.model' _description = '自定义模型' level1_id = fields.Many2one('model.level1', string='一级选项') level2_id = fields.Many2one('model.level2', string='二级选项', domain="[('level1_id', '=', level1_id)]") level3_id = fields.Many2one('model.level3', string='三级选项', domain="[('level2_id', '=', level2_id)]") level4_id = fields.Many2one('model.level4', string='四级选项', domain="[('level3_id', '=', level3_id)]")
2. 用on_change清理脏数据
上面的动态domain已经能实现选项筛选,但当上级字段切换时,下级字段的旧值可能还保留(比如选了一级A→二级A1,再切换一级B,二级A1还在),所以要加on_change方法清空后续字段:
@api.onchange('level1_id') def _onchange_level1(self): if not self.level1_id: self.level2_id = False self.level3_id = False self.level4_id = False @api.onchange('level2_id') def _onchange_level2(self): if not self.level2_id: self.level3_id = False self.level4_id = False @api.onchange('level3_id') def _onchange_level3(self): if not self.level3_id: self.level4_id = False
这样既实现了选项的层级筛选,又保证了数据的一致性。
场景二:基于Selection字段的动态选项联动
如果你的选择字段是自定义的下拉选项(不是关联其他模型),就需要用compute字段动态生成选项:
1. 定义字段和动态选项方法
class MyModel(models.Model): _name = 'my.model' _description = '自定义模型' level1 = fields.Selection([('group_a', 'A组'), ('group_b', 'B组')], string='一级选项') level2 = fields.Selection(selection='_get_level2_options', string='二级选项') level3 = fields.Selection(selection='_get_level3_options', string='三级选项') level4 = fields.Selection(selection='_get_level4_options', string='四级选项') # 二级选项根据一级选中值生成 @api.depends('level1') def _get_level2_options(self): options = [] if self.level1 == 'group_a': options = [('a1', 'A1子项'), ('a2', 'A2子项')] elif self.level1 == 'group_b': options = [('b1', 'B1子项'), ('b2', 'B2子项')] return options # 三级选项根据二级选中值生成 @api.depends('level2') def _get_level3_options(self): options = [] if self.level2 == 'a1': options = [('a1_1', 'A1-1'), ('a1_2', 'A1-2')] elif self.level2 == 'a2': options = [('a2_1', 'A2-1'), ('a2_2', 'A2-2')] elif self.level2 == 'b1': options = [('b1_1', 'B1-1')] return options # 四级选项同理 @api.depends('level3') def _get_level4_options(self): options = [] if self.level3 == 'a1_1': options = [('a1_1_1', '最终项1'), ('a1_1_2', '最终项2')] # 其他分支自行补充 return options
2. 补充on_change清理逻辑
同样,为了避免上级切换后下级保留无效选项,加上on_change清空后续字段:
@api.onchange('level1') def _onchange_level1(self): self.level2 = False self.level3 = False self.level4 = False @api.onchange('level2') def _onchange_level2(self): self.level3 = False self.level4 = False @api.onchange('level3') def _onchange_level3(self): self.level4 = False
这样就能实现完全的四级联动效果了。
内容的提问来源于stack exchange,提问作者user1632812
相关产品推荐
相关产品推荐

