Django REST Framework自定义动作使用不同序列化器返回空结果问题
解决DRF自定义Action返回空响应的问题
你的自定义action逻辑存在两个核心错误,导致返回空响应:
- 错误地将序列化器用于反序列化模式(传入
data=request.data),但这是一个GET请求的列表接口,需要的是序列化模式(传入数据库实例)。 - 没有传入要序列化的Author实例,且GET请求的
request.data本身就是空的,所以验证通过后返回空字典。
修正后的代码实现
根据你的需求(返回不带书籍列表的作者数据),修改视图集的action如下:
from rest_framework import status from rest_framework.response import Response from rest_framework import viewsets from .models import Author from .serializers import AuthorSerializer, AuthorNoBookListSerializer from django_filters.rest_framework import DjangoFilterBackend class AuthorViewSet(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['first_name', 'last_name'] @action(detail=False, serializer_class=AuthorNoBookListSerializer, methods=['get']) def no_booklist(self, request): # 可选:如果需要筛选**没有书籍的作者**,替换为下面的queryset # queryset = Author.objects.filter(books__isnull=True) queryset = self.get_queryset() # 序列化多个实例必须加many=True serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
关键修正点说明
- 指定HTTP方法:显式添加
methods=['get'],明确这是一个GET接口(默认也是GET,但显式声明更清晰)。 - 切换到序列化模式:不再传入
data=request.data,而是传入要序列化的queryset(数据库实例集合),DRF会自动处理为instance参数。 - 添加
many=True:因为是列表接口,需要序列化多个Author实例,必须指定该参数,否则只会返回单个对象(甚至报错)。 - 移除不必要的验证逻辑:GET请求没有提交数据,
serializer.is_valid()完全多余,直接返回序列化后的实例数据即可。
额外提示(非核心问题)
你的AuthorSerializer中book_list = serializers.ListField(source='books')可能不符合预期:books是反向关联的QuerySet,ListField默认处理原生列表数据,建议改为用关联字段,比如:
book_list = serializers.PrimaryKeyRelatedField(many=True, source='books', read_only=True)
或者如果需要嵌套书籍数据,使用书籍的序列化器。
内容的提问来源于stack exchange,提问作者Tsaari
相关产品推荐
相关产品推荐

