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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:35:37