Django DRF主URL下API方法创建及属性错误解决
问题解决:DRF ViewSet自定义Action报AttributeError
错误根源
你遇到的AttributeError: 'QuerySet' object has no attribute 'name',十有八九是这两个原因:
- 自定义
mainGroups接口直接返回了未经过序列化器处理的QuerySet对象 - 序列化器配置错误,用针对单个模型实例的逻辑去处理批量数据
DRF的ViewSet要求接口返回序列化后的响应,直接返回QuerySet会触发序列化器对单个对象的字段校验,自然找不到集合对象上的name属性。
正确实现代码
1. 修正CategoryViewSet的自定义Action
假设你的Category模型用parent外键字段标记父级分类(允许为空表示顶级分类),代码调整如下:
from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response from .models import Category from .serializers import CategorySerializer class CategoryViewSet(viewsets.ModelViewSet): queryset = Category.objects.all() serializer_class = CategorySerializer lookup_field = 'id' # 可根据实际需求改成slug等字段 # 自定义获取顶级分类的接口 @action(detail=False, methods=['get'], url_path='main-groups') def mainGroups(self, request): # 过滤出无父级的顶级分类 top_groups = Category.objects.filter(parent__isnull=True) # 用序列化器处理批量数据,必须加many=True serializer = self.get_serializer(top_groups, many=True) return Response(serializer.data)
2. 检查序列化器配置
确保你的CategorySerializer是正确的模型序列化器,示例如下:
from rest_framework import serializers from .models import Category class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = ['id', 'name', 'parent'] # 包含你需要返回的所有字段
3. 确认路由配置
确保ViewSet已正确注册到路由,urls.py示例:
from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import CategoryViewSet router = DefaultRouter() router.register(r'groups', CategoryViewSet, basename='category') urlpatterns = [ path('djangoadmin/', include(router.urls)), ]
此时自定义接口的访问地址为/djangoadmin/groups/main-groups/
核心注意事项
@action必须加detail=False:标记这是列表级接口,而非单个实例的接口- 序列化批量数据要加
many=True:告诉序列化器处理的是多个对象集合 - 绝对不能直接返回QuerySet:必须通过序列化器转换为DRF可处理的响应格式
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

