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

Django按状态分块划分模板 多for循环查询实现方案

结论

不要在模板层实现这类分组查询逻辑。Django模板的定位是仅负责展示层轻量渲染,本身被刻意限制了复杂数据处理能力,这类分组需求放在视图层配合ORM实现,查询效率更高、代码可维护性也更好。

具体实现方案

先给出参考模型定义,方便对齐逻辑:

# models.py
from django.db import models

class State(models.Model):
    # 状态编号,对应你提到的状态1、2、3
    code = models.IntegerField(unique=True)
    name = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return f"Status {self.code}"

class Project(models.Model):
    name_title_working = models.CharField(max_length=200)
    fk_state = models.ForeignKey(State, on_delete=models.PROTECT, related_name="projects")
    genre = models.CharField(max_length=100)
    d_conceived = models.DateField()

方案1:通过外键反向关联实现(推荐)

这个方案可以自动覆盖所有状态,哪怕某个状态下暂时没有项目也能正常渲染出对应标题,还能通过预加载避免N+1查询问题。
视图层代码:

# views.py
from django.shortcuts import render
from .models import State

def project_list(request):
    # prefetch_related会一次性预加载所有状态关联的项目,不会重复查库
    states = State.objects.prefetch_related("projects").all().order_by("code")
    return render(request, "project_list.html", {"states": states})

模板层代码完全不需要写查询逻辑,直接循环渲染即可:

<h1 class="main_title">Projects</h1>
{% for state in states %}
<h2>Projects with a Status of {{ state.code }}</h2>
{% for project in state.projects.all %}
<h3>> {{ project.name_title_working }}</h3>
<p>> {{ project.fk_state }}</p>
<p>> {{ project.genre }}</p>
<p>> {{ project.d_conceived }}</p>
{% empty %}
<p>当前状态下暂无项目</p>
{% endfor %}
{% endfor %}

方案2:分组聚合实现(仅展示有项目的状态)

如果不需要展示没有对应项目的空状态,可以在视图层对项目查询结果直接分组:

# views.py
from django.shortcuts import render
from itertools import groupby
from .models import Project

def project_list(request):
    # 注意:用groupby必须先按分组字段排序,否则会出现分组错误
    projects = Project.objects.select_related("fk_state").order_by("fk_state__code")
    project_groups = {}
    for state, group_items in groupby(projects, key=lambda x: x.fk_state):
        project_groups[state] = list(group_items)
    return render(request, "project_list.html", {"project_groups": project_groups})

对应模板:

<h1 class="main_title">Projects</h1>
{% for state, projects in project_groups.items %}
<h2>Projects with a Status of {{ state.code }}</h2>
{% for project in projects %}
<h3>> {{ project.name_title_working }}</h3>
<p>> {{ project.fk_state }}</p>
<p>> {{ project.genre }}</p>
<p>> {{ project.d_conceived }}</p>
{% endfor %}
{% endfor %}

为什么不推荐在模板层硬写逻辑

  • 模板没有原生分组能力,硬要实现需要写大量重复判断逻辑,会触发多次数据库查询,产生严重的N+1性能问题
  • 业务逻辑和展示逻辑强耦合,后续要调整分组规则、增加筛选条件时维护成本极高
  • 就算通过自定义模板标签实现,本质上还是把数据处理逻辑挪到了标签层,不如直接在视图层处理清晰直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:51:20