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

使用DRF时单类继承多APIView导致Swagger出现重复URL条目

解决DRF视图集成后Swagger接口重复问题

问题原因

当视图类同时继承ListAPIView和UpdateAPIView时,DRF-YASG(Swagger生成工具)会扫描所有父类支持的HTTP方法(ListAPIView支持GET,UpdateAPIView支持PUT/PATCH),再加上URL配置中未明确限定方法,就会导致每个URL下出现重复的接口条目。

解决方案

方案1:改用ViewSet(推荐)

ViewSet能清晰管理方法与URL的映射,DRF-YASG可自动识别正确接口,避免重复:

# views.py
from rest_framework import viewsets
from .models import YourModel
from .serializers import YourSerializer

class EscalatedStatusViewSet(viewsets.GenericViewSet, 
                              viewsets.mixins.ListModelMixin, 
                              viewsets.mixins.CreateModelMixin, 
                              viewsets.mixins.UpdateModelMixin):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer
# urls.py
from rest_framework.routers import DefaultRouter
from .views import EscalatedStatusViewSet

router = DefaultRouter()
router.register(r'escalated-status', EscalatedStatusViewSet, basename='escalated-status')

urlpatterns = [
    # 其他URL配置
    *router.urls,
]

此配置会让Swagger生成3条正确接口:

  • GET /escalated-status/(列表查询)
  • POST /escalated-status/(提交数据)
  • PUT /escalated-status/<pk>/(更新数据)

方案2:明确URL的actions并控制Swagger展示

如果不想改用ViewSet,可通过as_view(actions)限定每个URL的方法,并用DRF-YASG装饰器排除冗余方法:

# views.py
from rest_framework.generics import ListAPIView, UpdateAPIView
from rest_framework import status
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
from .models import YourModel
from .serializers import YourSerializer

class EscalatedStatusListView(ListAPIView, UpdateAPIView):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer

    # 实现POST方法(ListAPIView默认无此方法)
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    # 让Swagger在列表URL中忽略PUT/PATCH
    @swagger_auto_schema(auto_schema=None)
    def put(self, request, *args, **kwargs):
        return super().put(request, *args, **kwargs)

    @swagger_auto_schema(auto_schema=None)
    def patch(self, request, *args, **kwargs):
        return super().patch(request, *args, **kwargs)
# urls.py
from django.urls import path
from .views import EscalatedStatusListView

urlpatterns = [
    path('escalated-status/', 
         EscalatedStatusListView.as_view(actions={'get': 'list', 'post': 'post'}), 
         name='escalated-status-list'),
    path('escalated-status/<int:pk>/', 
         EscalatedStatusListView.as_view(actions={'put': 'update'}), 
         name='escalated-status-update'),
]

方案3:直接继承GenericAPIView并混入Mixin

避免继承完整的ListAPIView和UpdateAPIView,仅继承GenericAPIView并混入所需Mixin,精准控制支持的方法:

# views.py
from rest_framework import generics, mixins
from rest_framework import status
from rest_framework.response import Response
from .models import YourModel
from .serializers import YourSerializer

class EscalatedStatusListView(generics.GenericAPIView, 
                              mixins.ListModelMixin, 
                              mixins.UpdateModelMixin):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

URL配置同方案2,Swagger只会识别你手动实现的方法,不会生成重复条目。

内容的提问来源于stack exchange,提问作者Mohammed Yasin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:46:03