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

Django Rest Framework中如何按Category分组QuerySet?

嘿,刚好处理过类似的需求,给你几个实用的方案,根据你的场景选就行:

方案1:用Django预加载+构建分组字典(推荐,避免N+1查询)

你的模型已经给Category设置了related_name='items',我们可以利用Django的Prefetch来一次性加载所有关联数据,避免频繁查询数据库,然后构建一个清晰的分组结构:

from django.db.models import Prefetch

# 预加载所有分类及其关联的内容,也可以根据需求过滤分类(比如只查已发布的)
categories = Category.objects.prefetch_related(
    Prefetch('items', queryset=Item.objects.all())
).all()

# 构建分组字典,key是Category对象(或标题),value是对应Item列表
grouped_items = {}
# 先处理有分类的内容
for category in categories:
    # 这里可以用category.title作为key,方便后续展示
    grouped_items[category.title] = list(category.items.all())

# 单独处理没有分类的内容(category为null的Item)
uncategorized_items = Item.objects.filter(category__isnull=True).all()
if uncategorized_items:
    grouped_items['未分类'] = list(uncategorized_items)

这个方案只需要2次数据库查询,性能最优,而且能拿到完整的Category和Item对象,方便后续业务逻辑处理。

方案2:Python层面用itertools.groupby分组

如果你已经有了一批Item的QuerySet,想在内存里直接分组,可以用Python标准库的groupby,但要注意必须先按category排序,因为groupby只能对连续的相同键进行分组:

from itertools import groupby
from operator import attrgetter

# 先获取所有Item,按category字段排序(null值会被排到一起)
items = Item.objects.all().order_by('category')

# 按category属性分组,构建字典
grouped_items = {}
for key, item_group in groupby(items, key=attrgetter('category')):
    # 处理无分类的情况,key为None时用自定义名称
    category_name = key.title if key else '未分类'
    grouped_items[category_name] = list(item_group)

这个方案适合小数据量场景,如果Item数量很大,会把所有数据加载到内存,性能不如方案1。

方案3:用PostgreSQL的聚合函数(仅适用于PostgreSQL数据库)

如果你的项目用的是PostgreSQL,可以用ArrayAgg聚合函数直接在数据库层面完成分组,返回每个分类下的内容列表:

from django.contrib.postgres.aggregates import ArrayAgg
from django.db.models import Value
from django.db.models.functions import Coalesce

# 按分类分组,直接聚合出每个分类下的Item标题列表
grouped_data = Item.objects.values(
    # 用Coalesce处理null的分类,替换为自定义名称
    category_title=Coalesce('category__title', Value('未分类'))
).annotate(
    item_titles=ArrayAgg('title')
).order_by('category_title')

# 转成字典格式
grouped_items = {item['category_title']: item['item_titles'] for item in grouped_data}

这个方案完全在数据库层面完成分组,效率很高,但只支持PostgreSQL,且返回的是字段列表而非完整对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:54:36