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

DRF如何实现图书按分类分组返回及序列化方案咨询

DRF实现按分类分组返回最新图书的最优方案

方案说明

既可以用原生构造JSON返回,也可以通过DRF序列化器实现,以下实现兼顾性能、可维护性,完全解决你遇到的N+1查询、全局最新日期匹配、仅返回关联分类三个核心问题。

代码实现

1. 序列化器定义

只需要保留基础的图书字段序列化逻辑即可,无需自定义ListSerializer:

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Books
        fields = ("title", "author")

2. 视图实现

class BooksByRubricView(APIView):
    """按分类分组的最新图书列表"""
    def get(self, request):
        # 第一步:查询全局最新上传日期,仅1次SQL查询
        last_date = Books.objects.using('books').latest("date").date
        # 第二步:一次性查询所有最新日期的图书+关联分类数据,仅1次SQL查询,彻底解决N+1问题
        latest_books = Books.objects.using('books').filter(date=last_date).select_related('rubrics')
        # 第三步:遍历一次完成分组,无需额外查询
        result = {}
        for book in latest_books:
            # 无分类的图书可以统一归到未分类,按需调整
            if not book.rubrics:
                rubric_key = "未分类"
            else:
                # 如需key为rubric1、rubric2的格式,替换为下方注释代码
                # rubric_key = f"rubric{book.rubrics.id}"
                rubric_key = book.rubrics.rubric
            # 初始化分类对应的图书列表
            if rubric_key not in result:
                result[rubric_key] = []
            # 复用DRF序列化能力序列化单本图书
            result[rubric_key].append(BookSerializer(book).data)
        # DRF Response自动处理中文编码,无需额外配置参数
        return Response(result)

方案优势

  1. 总共仅执行2次SQL查询,性能远高于你之前的两种实现
  2. 仅返回存在最新图书的分类,不会返回Rubrics表全部分类
  3. 复用DRF序列化器能力,后续需要调整返回字段、添加校验规则时直接修改序列化器即可,可维护性更高
  4. 匹配全局最新日期规则,不会出现各分类单独取最新日期的问题

原有实现问题说明

  1. 你基于Rubrics查询的实现默认返回全部分类,且未做关联查询预加载,导致每个分类都单独查询图书列表,出现N+1问题
  2. 自定义ListSerializer中data.latest("date").date是取当前分类下图书的最新日期,不是全局最新日期,不符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 07:15:02