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

Django(MySQL)中避免循环查询高效重排模型对象的方法

优化方案:消除重排序接口的循环数据库查询

完全可以把逐次单条查询的逻辑改成批量查询,把N次数据库请求压缩到2次,适配你使用的MySQL环境。

你当前实现的核心性能问题是循环内调用Module.objects.get(id=module_id),传入N个模块ID就会产生N次单独的SELECT查询,属于典型的N+1查询问题,模块数量越多性能损耗越大。

具体实现思路

  • 第一步从请求参数中提取所有需要调整排序的模块ID,统一做类型转换,兼容前端传字符串ID的场景
  • 第二步用id__in过滤条件,一次性查询出所有目标模块对象,把原来的N次查询合并成1次
  • 可选增加参数合法性校验:如果传入的ID有对应不存在的模块,直接返回错误提示,避免静默失败
  • 遍历批量查出的模块对象,匹配对应ID设置排序值,最后用bulk_update完成批量更新,这一步本身就只会生成1条批量更新SQL,不会产生额外查询

优化后代码

from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework import status

@action(detail=False, permission_classes=[], methods=["PUT"])
def reorder_modules(self, request, *args, **kwargs):
    """
    ReOrdering Modules
    入参示例
    {
        "modules": {
            <module_id>: <ordering_number>,
            12: 2,
            13: 1,
            14: 3
        }
    }
    """
    module_order_map = request.data.get("modules", {})
    if not module_order_map:
        return Response({"detail": "缺少模块排序参数"}, status=status.HTTP_400_BAD_REQUEST)

    # 提取所有目标模块ID,统一转int,兼容字符串类型的ID传参
    target_ids = [int(mid) for mid in module_order_map.keys()]
    # 单次查询捞出所有目标模块,替代循环单条get
    module_list = list(Module.objects.filter(id__in=target_ids))

    # 校验非法ID
    if len(module_list) != len(target_ids):
        exist_id_set = {m.id for m in module_list}
        invalid_ids = [mid for mid in target_ids if mid not in exist_id_set]
        return Response(
            {"detail": f"模块ID不存在: {invalid_ids}"},
            status=status.HTTP_400_BAD_REQUEST
        )

    # 批量赋值排序字段
    for mod in module_list:
        # 兼容key为字符串/数字两种传参格式
        mod.order = module_order_map.get(str(mod.id), module_order_map.get(mod.id))

    Module.objects.bulk_update(module_list, ["order"])
    return Response({"detail": "successfully reordered course modules"}, status=status.HTTP_200_OK)

额外说明

  • 你原示例里的请求体有笔误:14, 3应该是14: 3,实际开发时要注意和前端约定好参数格式
  • Django的bulk_update在MySQL环境下可以正常工作,Django 2.2及以上版本都支持,更新100条数据的场景下,优化后数据库交互次数从原来的101次降到2次,性能提升非常明显

内容的提问来源于stack exchange,提问作者Shreehari Vaasistha L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:54:22