在单个APIView类中创建多个自定义GET请求时遭遇错误求助
Django REST Framework 多GET请求配置错误修复
我在使用Django REST Framework开发时,尝试在单个Sample APIView类中创建多个自定义GET请求,编写了对应的Views.py和Urls.py代码,但运行时出现错误,错误提示为:AssertionError: basename argument not specified, and could not automatically determine the name from the viewset, as it does not have a .queryset attribute.
我的Views.py代码
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class Sample(APIView): http_method_names = ['get', 'post', 'put', 'patch', 'delete'] def get(self, request): # 默认GET方法逻辑 response_data = {'message': 'Default GET method'} return Response(response_data, status=status.HTTP_200_OK) def get_fruits(self, request): # 自定义GET方法:获取水果列表 fruits = ["apple", "mango", "orange"] response_data = {'fruits': fruits} return Response(response_data, status=status.HTTP_200_OK) def get_films(self, request): # 自定义GET方法:获取电影列表 films = ["Saj", "don", "Man"] response_data = {"fnames": films} return Response(response_data, status=status.HTTP_200_OK)
我的Urls.py代码
from django.urls import path from .views import Sample from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'Apiapp', Sample, basename='Sample') urlpatterns = [ path('sample/get_fruits/', Sample.as_view({'get': 'get_fruits'}), name='custom-endpoint-1'), path('sample', Sample.as_view(), name='get-fruits'), path('sample/films/', Sample.as_view({'get': 'get_films'}), name='get-films'),]
问题原因及修复方案
错误根源
DefaultRouter的register()方法是为ViewSet类设计的,而你传入的Sample是APIView类,两者不兼容。Router会试图从ViewSet中获取queryset来自动生成路由名称,找不到就会抛出AssertionError,即使手动指定basename也无法解决这个本质不匹配的问题。
修复步骤
- 移除Router相关代码:APIView不需要通过Router注册,直接用
path配置URL即可。 - 统一URL路径规范:给
path('sample', ...)添加末尾斜杠,保持所有URL路径格式一致。
修改后的Urls.py代码:
from django.urls import path from .views import Sample urlpatterns = [ path('sample/', Sample.as_view(), name='default-get'), path('sample/get_fruits/', Sample.as_view({'get': 'get_fruits'}), name='custom-endpoint-1'), path('sample/films/', Sample.as_view({'get': 'get_films'}), name='get-films'), ]
可选优化(如果想使用Router)
如果希望用Router管理URL,可以将Sample改为ViewSet类,示例如下:
from rest_framework.viewsets import ViewSet from rest_framework.response import Response from rest_framework import status class SampleViewSet(ViewSet): def list(self, request): # 对应默认GET请求 response_data = {'message': 'Default GET method'} return Response(response_data, status=status.HTTP_200_OK) def get_fruits(self, request): fruits = ["apple", "mango", "orange"] return Response({'fruits': fruits}, status=status.HTTP_200_OK) def get_films(self, request): films = ["Saj", "don", "Man"] return Response({"fnames": films}, status=status.HTTP_200_OK)
对应的Urls.py:
from django.urls import path, include from .views import SampleViewSet from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'Apiapp', SampleViewSet, basename='Sample') urlpatterns = [ path('', include(router.urls)), # 额外添加自定义动作的路由 path('sample/get_fruits/', SampleViewSet.as_view({'get': 'get_fruits'}), name='custom-endpoint-1'), path('sample/films/', SampleViewSet.as_view({'get': 'get_films'}), name='get-films'), ]
不过如果只是需要多个GET端点,直接用APIView配合path配置的方式更简洁。
内容的提问来源于stack exchange,提问作者Naveen
相关产品推荐
相关产品推荐

