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

如何使用prefetch_related获取外键关联对象的name字段?

Django 一对多关联查询优化方案

1. 原有实现的性能问题

原有代码存在N+1查询问题:首次查询获取所有ModelA对象为1次查询,之后每遍历一个ModelA对象,都会单独发起一次数据库请求查询关联的ModelB对象,若存在100个ModelA对象,总查询次数会达到101次,是效率低下的核心原因。

2. 视图层核心优化(使用prefetch_related)

在视图中查询modela_list时,使用prefetch_related预加载关联的links数据,将总查询次数固定为2次:

# 替换原有视图中查询modela_list的代码
modela_list = ModelA.objects.prefetch_related("links").all()

prefetch_related的执行逻辑:

  • 第一次批量查询所有ModelA对象
  • 第二次批量查询所有上述ModelA对象关联的ModelB对象,在Python层面完成数据关联匹配,循环遍历关联数据时无需再访问数据库。

3. 模板代码修正

原有模板存在两处可修正的点:内层循环调用对象错误、模板标签语法空格错误,修正后代码如下:

{% for a in modela_list %}
 <p>{{ a.name }}</p>
    {% for link in a.links.all %}
        <p>Link name: {{ link.name }}</p>
    {% endfor %}
{% endfor %}

4. 进阶可选优化

如果仅需要用到ModelB的name字段,可以自定义Prefetch查询,仅拉取必要字段,减少数据库返回的数据量,进一步提升性能:

from django.db.models import Prefetch

modela_list = ModelA.objects.prefetch_related(
    Prefetch("links", queryset=ModelB.objects.only("name", "A_id"))
).all()

only方法指定仅查询name和关联外键A_id两个字段,避免加载ModelB其他无用字段。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 05:06:09