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

Django获取关联对象:如何输出Nomenclature及关联Changes全字段至模板

解决方案

你说得对,select_related确实不适用这个场景——它只能处理正向的外键/一对一关联(比如从Changes查询关联的Nomenclature),而你需要的是从Nomenclature反向查询它的所有Changes记录,这时候应该用prefetch_related。

1. 视图层优化查询(避免N+1问题)

在获取Nomenclature数据时,通过prefetch_related批量加载所有关联的Changes对象:

from django.shortcuts import render
from .models import Nomenclature

def nomenclature_list_view(request):
    # 预加载所有关联的Changes记录
    nomenclatures = Nomenclature.objects.all().prefetch_related('chamges')
    return render(request, 'your_template.html', {'nomenclatures': nomenclatures})

注:你的模型里related_name拼写错误(chamges应该是changes),建议修正,避免后续维护混淆。

2. 模板层渲染数据

在模板中遍历Nomenclature对象,同时输出其关联的所有Changes字段:

{% for nom in nomenclatures %}
    <div class="nomenclature-card">
        <h2>{{ nom.nameNom }} - {{ nom.numNom }}</h2>
        <div class="changes-section">
            <h3>变更记录:</h3>
            {% if nom.chamges.all %}
                <ul>
                    {% for change in nom.chamges.all %}
                        <li>
                            <p>调整数量:{{ change.quantity }}</p>
                            <p>安装位置:{{ change.location }}</p>
                            <p>经办人:{{ change.fullname }}</p>
                            <p>用途:{{ change.appointment }}</p>
                            <p>操作时间:{{ change.created_at|date:"Y-m-d H:i:s" }}</p>
                        </li>
                    {% endfor %}
                </ul>
            {% else %}
                <p>暂无变更记录</p>
            {% endif %}
        </div>
    </div>
{% endfor %}

补充说明

  • prefetch_related的工作逻辑:先执行一次SQL查询获取所有Nomenclature,再执行一次批量查询获取所有关联的Changes,最后在Python层面将两者关联,彻底避免了每个Nomenclature单独查询一次Changes的N+1性能问题。
  • 如果需要对关联的Changes进行过滤(比如只显示最近30天的记录),可以用Prefetch对象自定义查询:
from django.db.models import Prefetch
from datetime import timedelta
from django.utils import timezone

recent_changes = Changes.objects.filter(created_at__gte=timezone.now()-timedelta(days=30))
nomenclatures = Nomenclature.objects.all().prefetch_related(
    Prefetch('chamges', queryset=recent_changes, to_attr='recent_changes')
)

模板中就可以通过nom.recent_changes访问过滤后的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:35:17