Django嵌套for循环中如何获取每个spot对应的关联links数据
解决方法
问题根源
你原来的写法是把所有和当前文章关联spot的所有链接都查出来放到全局,没有和单个spot做绑定,所以每个spot下面都会显示全量的链接,无法对应到单个spot的专属链接。
第一步:优化模型定义(推荐)
Django支持多对多关系指定中间表,你可以直接在Spots模型中新增多对多关联字段,简化后续查询逻辑:
class Spots(models.Model): title = models.CharField(max_length=155) slug = models.SlugField(unique=True, max_length=155) # 新增多对多关联,通过中间表SpotLinks关联Links links = models.ManyToManyField(Links, through=SpotLinks, related_name='spots')
新增字段后执行makemigrations和migrate即可,不会影响现有数据。
第二步:修改views.py查询逻辑
查询spots的时候用prefetch_related预加载每个spot对应的关联links,避免模板循环时产生N次额外数据库查询:
def article(request, slug): article = get_object_or_404(Articles, slug=slug) # 预加载每个spot的关联links spots = Spots.objects.filter(articlespots__article=article).distinct().prefetch_related('links') context = { 'spots': spots, 'article': article, } return render(request, 'articletemplate.html', context)
数据查询逻辑建议统一放在views层处理,模板只负责渲染展示,符合Django的MTV设计规范,也方便后续维护
第三步:修改模板代码
第二层循环改为遍历当前spot自己的links集合即可:
{% for spot in spots %} <div> <h2>{{ spot.title }}</h2> </div> {% for link in spot.links.all %} <div> <h3>{{ link.url }}</h3> </div> {% empty %} <div>该点位暂无关联链接</div> {% endfor %} {% endfor %}
无需修改模型的替代方案(不推荐)
如果不想调整模型定义,也可以直接在模板中做关联匹配,但会产生N+1查询问题,数据量大时性能很差:
{% for spot in spots %} <div> <h2>{{ spot.title }}</h2> </div> {% for link in links %} {% if link.spotlinks_set.all.0.spot.id == spot.id %} <div> <h3>{{ link.url }}</h3> </div> {% endif %} {% endfor %} {% endfor %}
内容的提问来源于stack exchange,提问作者haashe
相关产品推荐
相关产品推荐

