You need to enable JavaScript to run this app. Odoo中如何创建基于条件的动态Selection选择字段?
优惠活动
大模型
产品
解决方案
定价
更多

Odoo中如何创建基于条件的动态Selection选择字段?

原实现逻辑错误说明

  • Odoo 原生 fields.Selection 传入方法名作为selection参数时,该方法是模型级别的全局回调,仅会在字段初始化、模块升级等节点执行一次生成全局统一的选项列表,不支持根据单条记录的字段值返回不同的选项,原写法的设计思路不符合字段的底层逻辑。
  • 方法内部对self循环后直接return,只会处理第一条记录就终止执行,代码逻辑本身存在缺陷。
  • 即使方法可以执行,返回的单条记录对应的选项会被所有记录共用,会出现所有记录的选项都匹配第一条记录字段值的错误。

可行调整方案

方案1:全量定义选项 + onchange + 视图动态过滤(最常用,适配原生逻辑)

  1. 先把所有可能的选项全量定义在Selection字段中:
x_material_orientation = fields.Selection(
    selection=[
        ('sheetfaceup','Sheets Face Up'),
        ('sheetfacedown','Sheets Face Down'),
        ('windfaceout','Wind Face Out'),
        ('windfacein','Wind Face In'),
    ],
    string='Material Orientation'
)
  1. 新增x_order_customer_uom的onchange方法,自动清空不符合当前单位的选项值:
@api.onchange('x_order_customer_uom')
def _onchange_filter_material_orientation(self):
    # 无单位时清空选项
    if not self.x_order_customer_uom:
        self.x_material_orientation = False
        return
    uom_name = self.x_order_customer_uom.name
    if uom_name == 'sht':
        allowed_opts = ['sheetfaceup', 'sheetfacedown']
    elif uom_name == 'yds':
        allowed_opts = ['windfaceout', 'windfacein']
    else:
        allowed_opts = []
    # 当前选项不在允许列表内则清空
    if self.x_material_orientation not in allowed_opts:
        self.x_material_orientation = False
  1. 在该字段的视图定义中增加domain属性,动态过滤可选选项:
<field name="x_order_customer_uom"/>
<field name="x_material_orientation" 
       domain="[('value', 'in', (x_order_customer_uom.name == 'sht') ? ['sheetfaceup', 'sheetfacedown'] : ['windfaceout', 'windfacein'])]"/>

方案2:用Many2one字段替代Selection(适合选项多、后续需要扩展的场景)

如果后续还有更多单位对应的方向选项需要新增,可以单独建立一个Material Orientation数据模型,存储选项值、显示名、匹配的单位,然后把字段改为Many2one类型,直接通过domain动态过滤关联的选项记录,可维护性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 08:48:02