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

Odoo search方法优化:将allocated_sale_order查询移出循环

优化Odoo销售订单test方法:移除循环内数据库查询

在销售订单的onchange关联方法中,原test逻辑会在循环里逐个查询关联销售订单,导致多次数据库请求。下面是优化后的代码,将循环内的查询逻辑移到外部,提升执行效率:

def test(self):
    tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
    date_list = [(tomorrow + datetime.timedelta(days=x)).date() for x in range(30)]

    # 查询符合条件的技师排班明细
    technician_line = self.env["allocated_technician_line"].search(
        [
            ("service_type_id", "=", self.service_type_id.id),
            ("time_slot", "=", self.time_slot),
            ("technician_id.user_id", "in", self.area_id.technicians.ids),
            ("allocated_technician_id.date", "in", date_list),
        ]
    )
    if not technician_line:
        self["assigned_asc"] = False
        return

    # 收集所有需要查询的维度,一次性获取关联销售订单
    active_id = self.env.context.get('active_id')
    domain = [
        ("preferred_service_schedule", "in", technician_line.mapped('allocated_technician_id.id')),
        ("service_type_id", "in", technician_line.mapped('service_type_id.id')),
        ("time_slot", "=", self.time_slot),
        ("state", "!=", "cancel"),
    ]
    if active_id:
        domain.append(("id", "!=", active_id))
    
    sale_orders = self.env["sale.order"].search(domain)

    # 构建订单统计映射:按(排班ID,服务类型ID)分组计数
    order_count_map = {}
    for order in sale_orders:
        key = (order.preferred_service_schedule.id, order.service_type_id.id)
        order_count_map[key] = order_count_map.get(key, 0) + 1

    # 遍历技师明细,计算可用配额并收集符合条件的排班ID
    allocated_technician_schedule_ids = []
    for line in technician_line:
        key = (line.allocated_technician_id.id, line.service_type_id.id)
        order_count = order_count_map.get(key, 0)
        available_allocation = line.allocation - order_count
        if available_allocation > 0:
            allocated_technician_schedule_ids.append(line.allocated_technician_id.id)

    # 处理assigned_asc字段
    if allocated_technician_schedule_ids:
        allocated_recs = self.env["allocated_technician"].browse(allocated_technician_schedule_ids)
        user_ids = allocated_recs.mapped('user_id').ids
        if self.assigned_asc.id not in user_ids:
            self["assigned_asc"] = False
    else:
        self["assigned_asc"] = False

优化要点

  • 合并数据库查询:把原循环内的N次sale.order查询合并成1次批量查询,大幅减少数据库交互开销。
  • 用映射统计订单数:通过一次遍历查询结果,构建以「排班ID+服务类型ID」为键的计数映射,后续循环直接取统计值,避免重复处理订单集合。
  • 提前判空精简逻辑:查询到technician_line为空时直接设置字段并返回,跳过后续无意义的步骤。
  • 统一过滤条件:把当前订单ID的过滤逻辑直接整合到查询domain中,替代循环内的filtered操作,减少内存处理成本。

内容的提问来源于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.19 14:40:28