Odoo15字段区域搜索方法优化及filtered空结果问题求助
问题解决与优化方案
一、解决filtered返回空记录集的问题
你用self.env['tech_line'].filtered(...)得到空结果的核心原因:
- Odoo中,
self.env['model']默认是空记录集,filtered()方法只能对已经加载到内存中的记录进行过滤,无法直接从数据库查询数据。而search()是直接向数据库发起查询,能返回符合条件的所有记录。
修正方式:
- 如果一定要用
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) - 更合理的方式:直接用
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
相关产品推荐
相关产品推荐

