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
相关产品推荐
相关产品推荐

