You need to enable JavaScript to run this app. Odoo中基于selection字段修改Many2one字段domain不生效如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Odoo中基于selection字段修改Many2one字段domain不生效如何解决

问题原因
    1. domain逻辑错误触发降级:你的search_value是关联customer.regist的Many2one字段,该字段底层存储的是关联记录的id值,你当前写的domain用name in 名称列表、phone in 手机号列表,实际上是拿id和名称/手机号做匹配,完全无法命中有效记录,Odoo识别到无效domain后会自动回退到模型定义的默认domain。
    1. 查询逻辑冗余:提前全量查询所有customer.regist记录再拼接值列表的写法,数据量稍大就会触发性能问题,且完全没有必要。
    1. 其他排查点:确认search_value字段的comodel_name确实是customer.regist,如果关联模型不对,domain中的name、phone字段不存在也会导致domain失效;同时检查视图中search_value字段是否加了force_domain属性,该属性会强制使用视图定义的domain,忽略onchange返回的domain。
修复方案

直接简化domain写法,不需要提前查询全量记录,修正后的代码如下:

@api.onchange('search_by')
def _get_partner(self):
    res = {'domain': {'search_value': []}}
    # 对应原逻辑的基础过滤条件
    base_domain = [('name', '!=', 'New')]
    if self.search_by == 'code':
        res['domain']['search_value'] = base_domain
    if self.search_by == 'phone':
        # 过滤出有手机号的有效记录
        res['domain']['search_value'] = base_domain + [('phone', '!=', False)]
    return res

如果你需要切换search_by时,search_value的下拉选项显示内容同步切换为名称/手机号,还需要额外适配name_get方法:
先修改onchange方法传递上下文标识:

@api.onchange('search_by')
def _get_partner(self):
    res = {'domain': {'search_value': []}, 'context': {}}
    base_domain = [('name', '!=', 'New')]
    if self.search_by == 'code':
        res['domain']['search_value'] = base_domain
        res['context']['display_by_name'] = True
    if self.search_by == 'phone':
        res['domain']['search_value'] = base_domain + [('phone', '!=', False)]
        res['context']['display_by_phone'] = True
    return res

再在customer.regist模型中重写name_get:

def name_get(self):
    if self.env.context.get('display_by_phone'):
        return [(record.id, record.phone) for record in self]
    return super().name_get()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 00:15:03