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

Django中get_queryset循环因GUID过滤产生重复SQL查询的解决办法

解决Django get_queryset中重复SQL查询的问题

你的问题出在循环内重复执行数据库查询:每次调用all_sections.filter(GUID=budget.SectionGUID)都会触发一次新的SQL查询——因为Django的QuerySet是惰性求值的,每次循环都会访问数据库。哪怕你提前获取了all_sections = CleanSections.objects.all(),filter操作会生成新的QuerySet,依然会发起重复请求。

优化方案:提前构建GUID到对象的映射字典

一次性从数据库取出所有CleanSections数据,存入以GUID为键的字典中,循环时直接通过GUID取值,全程只执行1次SQL查询。

修改后的代码如下:

def get_queryset(self):
    session = requests_cache.CachedSession('budget_cache', backend=backend, stale_if_error=True,
                                           expire_after=360)
    url = config('API') + 'BUDGET'
    response = session.get(url, auth=UNICA_AUTH)

    # 补上API响应解析逻辑(原代码遗漏了这一步)
    try:
        response_json = response.json()
    except ValueError:
        print('JSON解析失败')
        return []

    queryset = []

    # 提前构建GUID到CleanSection对象的映射字典,仅执行1次SQL查询
    section_map = {section.GUID: section for section in CleanSections.objects.all()}

    for item in response_json:
        parsed_json = ReportProjectBudgetSerializer.parse_raw(json.dumps(item))

        if parsed_json.ObjectGUID != select_front:
            continue

        for budget in parsed_json.BudgetData:
            # 直接从内存字典取对应对象,无需再查数据库
            budget.SectionGUID = section_map.get(budget.SectionGUID)
            budget.СompletedContract = budget.СompletedContract * 100
            budget.СompletedEstimate = budget.СompletedEstimate * 100
            queryset.append(budget)
    
    return queryset

关键优化点说明

  • section_map = {section.GUID: section for section in CleanSections.objects.all()}:一次性拉取所有CleanSections数据,生成键为GUID的字典,仅触发1次SQL查询。
  • 循环内用section_map.get(budget.SectionGUID)替代filter:直接从内存字典取值,完全避免重复数据库请求。
  • 简化了原代码的条件判断逻辑,去掉冗余的obj赋值,让代码更简洁。

另外提个小问题:原代码里response_json初始化为None,但没有对API响应做解析,实际运行时else分支永远不会执行,修改后的代码已补上这部分处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:33:25