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

Django REST Framework自定义动作使用不同序列化器返回空结果问题

解决DRF自定义Action返回空响应的问题

你的自定义action逻辑存在两个核心错误,导致返回空响应:

  1. 错误地将序列化器用于反序列化模式(传入data=request.data),但这是一个GET请求的列表接口,需要的是序列化模式(传入数据库实例)。
  2. 没有传入要序列化的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:20:33