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

Django外键嵌套循环问题:如何展示音乐流派及子流派

修正Django中按流派展示对应子流派的问题

问题根源

你的模板循环逻辑错误:subgenres是所有子流派的QuerySet,并非当前单个流派关联的子集合;且Django外键的反向关联默认命名为[模型名小写]_set,因此不能用subgenres.genre.all来获取当前流派的子流派。

修正方案

方案1:快速修改模板

无需改动视图,仅修正模板内的子流派循环逻辑:
将原模板中的:

{% for subgenre in subgenres.genre.all %}

替换为:

{% for subgenre in genre.subgenre_set.all %}

由于Subgenre的genre外键指向Genre,Django会自动为Genre生成反向关联属性subgenre_set,通过它可直接获取当前流派对应的所有子流派。

方案2:优化模型命名(提升代码可读性)

若想让反向关联的命名更直观,可在Subgenre模型的外键字段中添加related_name参数:

class Subgenre(models.Model):
    subgenre_id = models.AutoField(primary_key=True)
    code = models.CharField(unique=True, max_length=6)
    description = models.CharField(max_length=25, blank=False, null=False)
    # 添加related_name,自定义反向关联名称
    genre = models.ForeignKey(Genre, on_delete=models.CASCADE, related_name='subgenres')

    class Meta:
        managed = False
        db_table = 'subgenre'
        db_table_comment = 'Music subgenre catalog'

    def __str__(self):
        return self.description

修改后,模板中即可使用更清晰的命名:

{% for subgenre in genre.subgenres.all %}

方案3:优化视图性能(避免N+1查询问题)

当流派数量较多时,每个流派单独查询子流派会触发多次数据库查询(N+1问题),可通过prefetch_related提前批量加载所有子流派:
修改views.py中的代码:

def new_playlist(request):
    # 提前预加载每个流派对应的子流派,减少数据库查询次数
    genres = Genre.objects.all().order_by('description').prefetch_related('subgenres')
    # 无需再单独传递subgenres到上下文
    context = { 'genres': genres }
    return render(request,"applications/ecommerce/playlists/new-playlist.html",context)

注:若未设置related_name,则将prefetch_related('subgenres')改为prefetch_related('subgenre_set')即可。

最终完整模板示例(含空状态处理)

结合方案2和3,模板代码可优化为:

{% for genre in genres %}
<div class="card">
   <div class="card-header">
      <h5 class="mb-0">{{genre.description}}</h5>
   </div>
   <div class="card-body">
      {% for subgenre in genre.subgenres.all %}
      <div class="row">
         <label>{{subgenre.description}}</label>
      </div>
      {% empty %}
      <div class="row">
         <label>暂无子流派</label>
      </div>
      {% endfor %}
   </div>
</div>
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:48:15