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

在单个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也无法解决这个本质不匹配的问题。

修复步骤

  1. 移除Router相关代码:APIView不需要通过Router注册,直接用path配置URL即可。
  2. 统一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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:22:57