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

Odoo15字段区域搜索方法优化及filtered空结果问题求助

问题解决与优化方案

一、解决filtered返回空记录集的问题

你用self.env['tech_line'].filtered(...)得到空结果的核心原因:

  • Odoo中,self.env['model']默认是空记录集,filtered()方法只能对已经加载到内存中的记录进行过滤,无法直接从数据库查询数据。而search()是直接向数据库发起查询,能返回符合条件的所有记录。

修正方式:

  1. 如果一定要用filtered,需要先获取完整的tech_line记录集(数据量大时不推荐,会占用过多内存),再过滤:
    # 先获取所有tech_line记录,再过滤
    all_tech_lines = self.env['tech_line'].search([])
    al_a6 = all_tech_lines.filtered(lambda rec: rec.service_type_id.id == self.service_type_id.id)
    
  2. 更合理的方式:直接用search()完成过滤(你原来的tech_line = tech_line.search(...)已经实现了这个逻辑,al_a6其实和tech_line结果一致,没必要重复处理)。

二、代码卡顿优化方案

你的代码卡顿主要是循环内重复发起数据库查询(N+1问题),每次循环都调用territory.search(),会频繁访问数据库,导致性能下降。以下是优化思路:

1. 批量查询,避免循环内的数据库操作

先收集所有需要的用户ID,再一次性查询关联的territory:

def test(self):
    # 1. 一次性查询符合条件的tech_line,预加载关联字段避免额外查询
    tech_line = self.env['tech_line'].search(
        [('service_type_id', '=', self.service_type_id.id)],
        prefetch=['technician_allociated_id', 'technician_allociated_id.user_id']
    )
    
    # 2. 收集所有关联的用户ID(过滤掉空值避免报错)
    user_ids = [tec.technician_allociated_id.user_id.id for tec in tech_line if tec.technician_allociated_id.user_id]
    
    # 3. 一次性查询所有符合条件的territory
    territories = self.env['territory'].search([('technicians', 'in', user_ids)])
    
    # 4. 整理结果(用记录集的ids属性直接获取ID列表,自动去重)
    area = territories.ids
    
    print('##################33', len(area))
    print('$$$$$$$$$$$$$$$$$$$', tech_line)

2. 其他优化细节

  • 移除循环内重复的模型初始化:比如territory = self.env['territory']放在循环外,或者直接使用self.env['territory'],没必要每次循环都重新赋值。
  • 用记录集替代列表存储ID:Odoo的记录集自带很多便捷方法,直接操作记录集比列表更高效,也更符合Odoo的开发规范。
  • 按需预加载关联字段:通过prefetch参数在查询时预加载需要的关联字段,避免访问关联字段时触发额外的数据库查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:13:12