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

如何修改Odoo 10中mail.message模型的默认搜索字段为body?

问题描述

我想修改Odoo中mail.message模型的默认搜索逻辑:

  • 当前搜索关键词(比如“Hello”)会返回record_name字段包含该词的消息,但我需要改为匹配body字段
  • 由于mail.thread模型有指向mail.message的One2many字段,很多模型(如sale.order)继承自mail.thread,所以在sale.order的搜索视图中进行“Messages”高级搜索时,同样需要匹配body而非record_name

我自己重写了_name_search方法,代码如下:

@api.model
def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
    result = super(MailMessage, self)._name_search(
        name=name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid
    )
    mms = self.env['mail.message'].search([]).filtered(
        lambda r: name in r.body
    )
    l = [(r.id, r.record_name) for r in mms]
    return l

这个方法目前能运行,但我担心它无法适配所有场景,比如大数据量下的性能问题,或者破坏原有搜索逻辑,想找更优的实现方案,求指导。


优化方案

你的思路方向是对的,但当前实现确实存在几个明显的问题,会影响兼容性和生产环境的性能,这里给你一个更稳健的优化方案:

当前实现的问题点

  • 性能瓶颈:self.env['mail.message'].search([])会拉取系统中所有消息记录,再用filtered做客户端过滤,数据量一大就会严重拖慢系统,完全不适合生产环境。
  • 丢失原有过滤逻辑:你没有结合原方法传入的args参数,会丢失其他已有的搜索过滤条件(比如按消息类型、关联模型过滤等)。
  • 不支持搜索运算符:硬写name in r.body只支持精确匹配,原方法的operator参数(比如ilike、like)完全没用到,不符合Odoo的搜索逻辑规范。

推荐的优化代码

@api.model
def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
    # 处理默认参数,避免None值报错
    args = args or []
    if name:
        # 方案1:同时匹配record_name和body(保留原有逻辑的同时新增body搜索)
        combined_domain = args + ['|', ('record_name', operator, name), ('body', operator, name)]
        
        # 如果你想完全替换为只匹配body,就用下面这行替换上面的combined_domain
        # combined_domain = args + [('body', operator, name)]
        
        # 直接在数据库层面执行搜索,性能远高于客户端过滤
        matching_records = self.search(combined_domain, limit=limit)
        # 返回标准的(id, display_name)格式,符合_name_search的返回要求
        return matching_records.name_get()
    # 当没有搜索关键词时,调用父类方法保持原有逻辑
    return super()._name_search(name=name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)

额外说明

  • 这个实现会自动适配所有继承mail.thread的模型(比如sale.order)的“Messages”高级搜索,因为这些模型的消息搜索最终都会调用mail.message的_name_search方法。
  • 用search做数据库层面的过滤,能充分利用数据库索引,性能比客户端filtered提升几个量级。
  • 保留了原方法的所有参数,不会破坏原有业务逻辑的兼容性。
  • 如果你的Odoo版本是14+,也可以考虑通过修改模型的_search方法或者调整搜索视图的默认字段,但重写_name_search是最直接且兼容性最好的方式,因为它专门负责名称搜索的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:00:31