Odoo中如何创建基于条件的动态Selection选择字段?
原实现逻辑错误说明
- Odoo 原生
fields.Selection传入方法名作为selection参数时,该方法是模型级别的全局回调,仅会在字段初始化、模块升级等节点执行一次生成全局统一的选项列表,不支持根据单条记录的字段值返回不同的选项,原写法的设计思路不符合字段的底层逻辑。 - 方法内部对
self循环后直接return,只会处理第一条记录就终止执行,代码逻辑本身存在缺陷。 - 即使方法可以执行,返回的单条记录对应的选项会被所有记录共用,会出现所有记录的选项都匹配第一条记录字段值的错误。
可行调整方案
方案1:全量定义选项 + onchange + 视图动态过滤(最常用,适配原生逻辑)
- 先把所有可能的选项全量定义在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' )
- 新增
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
- 在该字段的视图定义中增加
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
相关产品推荐
相关产品推荐

