Odoo17中如何添加依赖其他字段值的动态更新选择字段
Odoo动态更新选择字段选项的解决方案
需求:实现选择字段field2的选项随字段field1的值变化立即动态更新。
原有方案问题分析
方案1问题
class SomeModel(models.Model): field1 = fields.Integer(store=False) field2 = fields.Selection(store=False, selection='comp_fl2') @api.onchange('field1') def _time_fields(self): self.field2 = False def comp_fl2(self): if self.field1: if self.field1 > 5: return[('one','one'),('two','two')] else: return [('three', 'three'), ('four', 'four')] return []
selection参数指定的方法属于模型级别方法,默认无法获取前端输入的field1临时值(store=False的字段未保存时,值仅存在于前端上下文,模型方法访问的是数据库记录值,此处无对应存储),因此comp_fl2无法拿到field1的实时输入值。
方案2问题
@api.onchange('field1') def comp_fl2(self): if self.field1: if self.field1 > 5: return[('one','one'),('two','two')] else: return [('three', 'three'), ('four', 'four')] return []
@api.onchange装饰的方法要求返回包含domain/value/warning等键的字典,直接返回选项列表不符合方法规范,导致逻辑不生效。
正确实现代码
class SomeModel(models.Model): _name = 'some.model' field1 = fields.Integer(store=False) # 初始绑定默认选项方法 field2 = fields.Selection(store=False, selection=lambda self: self._get_default_field2_selection()) def _get_default_field2_selection(self): # 默认返回空选项,可根据需求调整 return [] @api.onchange('field1') def _onchange_field1(self): # 根据field1实时值生成对应选项 if self.field1 and self.field1 > 5: new_selection = [('one', 'One'), ('two', 'Two')] elif self.field1 and self.field1 <= 5: new_selection = [('three', 'Three'), ('four', 'Four')] else: new_selection = [] # 动态更新field2的选项列表 self._fields['field2'].selection = lambda self: new_selection # 清空field2当前值,避免旧值与新选项不匹配 self.field2 = False # 通知前端更新字段状态 return { 'value': {'field2': False}, 'domain': {'field2': [('value', 'in', [val for val, _ in new_selection])]} }
实现说明
- 初始通过
lambda绑定默认选项方法,保证字段初始化时的基础配置。 - 在
_onchange_field1方法中,实时读取前端输入的field1值,生成对应的选项列表。 - 修改
self._fields['field2'].selection动态更新选择字段的选项(用lambda包装是因为selection参数要求传入可调用对象)。 - 清空
field2的当前值,防止旧值不在新选项集合中引发前端错误。 - 返回包含
value和domain的字典,明确通知前端更新字段值与可选范围。
内容的提问来源于stack exchange,提问作者Yagub Guseynov
相关产品推荐
相关产品推荐

