DRF实现分类列表接口:路由选择与ListAPIView的list()方法重写疑问
解决DRF分类列表的路由与视图需求
需求说明
- 访问
example.com/api/categories:获取无父级的分类列表 - 访问
example.com/api/categories/{id_here}:获取指定ID分类的子分类列表
现有代码
models.py
class Category(models.Model): name = models.CharField(max_length=100) parent_category = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='subcategories')
原views.py
class CategoryList(generics.ListAPIView): queryset = Category.objects.all() serializer_class = CategorySerializer
解决方案
1. 修改视图类
无需重写list()方法,直接重写get_queryset()即可根据URL参数动态返回对应数据:
from rest_framework import generics from django.http import Http404 from .models import Category from .serializers import CategorySerializer class CategoryList(generics.ListAPIView): serializer_class = CategorySerializer def get_queryset(self): # 提取URL中的分类ID参数 category_id = self.kwargs.get('pk') if category_id: # 验证指定ID的分类是否存在,不存在则返回404 try: Category.objects.get(pk=category_id) except Category.DoesNotExist: raise Http404("目标分类不存在") # 返回该分类的所有子分类 return Category.objects.filter(parent_category_id=category_id) else: # 返回无父级的根分类 return Category.objects.filter(parent_category__isnull=True)
2. 配置URL路由
使用Django原生path即可实现需求,无需额外依赖DRF路由扩展:
urls.py
from django.urls import path from .views import CategoryList urlpatterns = [ # 根分类列表接口 path('api/categories', CategoryList.as_view(), name='root-category-list'), # 指定分类的子分类列表接口 path('api/categories/<int:pk>', CategoryList.as_view(), name='subcategory-list'), ]
说明
- 利用
get_queryset()的动态特性,根据URL中是否存在pk参数返回不同查询集,精准匹配两个需求场景 - 新增分类存在性校验,避免请求不存在的分类ID时返回空列表,改为返回标准404响应
内容的提问来源于stack exchange,提问作者Seyedmahdi moosavyan
相关产品推荐
相关产品推荐

