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

Django REST Framework过滤查询集时仅单次访问数据库的方法

解决Django REST Framework中查询集N+1查询问题

问题根源

你碰到的N次SELECT冗余查询,核心原因不是返回查询集本身,而是序列化器中包含了未预取的关联模型字段。Django查询集是惰性求值的,返回Model.objects.filter(...)本身不会触发数据库查询,但当DRF序列化每条数据时,若访问了未预取的关联对象,就会为每条数据单独发起一次SELECT请求,形成N+1查询。而你尝试的list()只是提前加载主表数据到内存,既解决不了关联字段的N+1问题,还会额外增加内存开销导致响应变慢。

解决方案

直接在查询集里用Django提供的预取方法,一次性把关联数据拉取回来,避免多次查询:

  1. 针对外键/一对一关联:使用select_related
    如果你的Model包含外键或一对一类型的关联字段(比如author),修改get_queryset方法:
class ModelViewset(ListModelMixin, viewsets.GenericViewSet):
    def get_queryset(self):
        # 替换为你的关联字段名
        return Model.objects.filter(category=value).select_related('author')
  1. 针对多对多/反向外键关联:使用prefetch_related
    如果是多对多字段(比如tags)或反向外键关联,用这个方法:
class ModelViewset(ListModelMixin, viewsets.GenericViewSet):
    def get_queryset(self):
        # 替换为你的关联字段名
        return Model.objects.filter(category=value).prefetch_related('tags')
  1. 精简序列化器字段
    如果序列化器中有些关联字段不是接口必需的,直接移除这些字段,从根源上避免不必要的关联查询。

补充说明

  • select_related是通过SQL的JOIN语句一次性拉取关联数据,适合一对一/外键这类单条关联的场景。
  • prefetch_related是先拉取主表数据,再批量拉取关联表数据,适合多对多、反向外键这类多条关联的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:29:54