在Django DRF中如何分组相同字段值并关联展示对应字段
按作者分组展示图书列表的解决方案
你需要将相同作者的图书合并到同一条目下,以下是两种可行的实现方式:
方法一:Python内存分组(兼容所有数据库)
这种方式先从数据库获取所有图书数据,再在内存中按作者分组,适配所有数据库类型。
修改 views.py
from collections import defaultdict from rest_framework.response import Response from rest_framework.views import APIView from .models import Book from .serializers import AuthorBookSerializer class BookAuthors(APIView): def get(self, request): books = Book.objects.all() # 初始化字典,按作者分组存储对应书名 author_book_map = defaultdict(list) for book in books: author_book_map[book.author].append(book.title) # 转换为接口所需的结构化数据 grouped_data = [ {"author": author, "titles": titles} for author, titles in author_book_map.items() ] serializer = AuthorBookSerializer(grouped_data, many=True) return Response(serializer.data)
修改 serializers.py
新增适配分组结构的序列化器:
from rest_framework import serializers class AuthorBookSerializer(serializers.Serializer): author = serializers.CharField(max_length=100) titles = serializers.ListField(child=serializers.CharField(max_length=150))
方法二:数据库层面分组(PostgreSQL专属,性能更优)
如果项目使用PostgreSQL数据库,可直接利用数据库聚合函数完成分组,性能比内存分组更高效。
修改 views.py
from django.db.models import ArrayAgg from rest_framework.response import Response from rest_framework.views import APIView from .models import Book from .serializers import AuthorBookSerializer class BookAuthors(APIView): def get(self, request): # 数据库层面按author分组,聚合关联的title为列表 grouped_authors = Book.objects.values('author').annotate( titles=ArrayAgg('title', distinct=True) # distinct可选,用于过滤重复书名 ).order_by('author') serializer = AuthorBookSerializer(grouped_authors, many=True) return Response(serializer.data)
序列化器使用
直接复用方法一中的 AuthorBookSerializer 即可。
效果对比
修改前接口返回示例:
[ {"title": "伊利亚特", "author": "Homer"}, {"title": "奥德赛", "author": "Homer"}, {"title": "理想国", "author": "Plato"} ]
修改后接口返回示例:
[ {"author": "Homer", "titles": ["伊利亚特", "奥德赛"]}, {"author": "Plato", "titles": ["理想国"]} ]
内容的提问来源于stack exchange,提问作者Stefan Vukovic
相关产品推荐
相关产品推荐

