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

API在Postman/ThunderClient正常,集成Swagger后无参数显示求助

问题描述

我的API在Postman或ThunderClient中测试完全正常,但集成Swagger后,Swagger UI里完全不显示任何API参数。

相关截图说明

  • 图片1:Swagger UI界面中无任何API参数展示
  • 图片2:注册端点仅显示基础状态,无请求参数
  • 图片3:登录端点同样仅展示状态,无参数区域

我的views.py代码片段

from rest_framework.response import Response
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.views import APIView
from account.serializers import (
    SendPasswordResetEmailSerializer,
    UserChangePasswordSerializer,
    UserLoginSerializer,
    UserPasswordResetSerializer,
    UserProfileSerializer,
    UserRegistrationSerializer,
)
from django.contrib.auth import authenticate
from account.renderers import UserRenderer
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.permissions import IsAuthenticated
from drf_yasg.utils import swagger_auto_schema

手动生成Token函数

def get_tokens_for_user(user):
    refresh = RefreshToken.for_user(user)
    return {
        "refresh": str(refresh),
        "access": str(refresh.access_token),
    }

UserRegistrationView

class UserRegistrationView(GenericAPIView):
    renderer_classes = [UserRenderer]

    def post(self, request, format=None):
        serializer = UserRegistrationSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        token = get_tokens_for_user(user)
        return Response(
            {"token": token, "msg": "Registration Successful"},
            status=status.HTTP_201_CREATED,
        )

UserLoginView

class UserLoginView(APIView):
    renderer_classes = [UserRenderer]

    def post(self, request, format=None):
        serializer = UserLoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        email = serializer.data.get("email")
        password = serializer.data.get("password")
        user = authenticate(email=email, password=password)
        
        if user is not None:
            token = get_tokens_for_user(user)
            return Response(
                {"token": token, "msg": "Login Success"}, status=status.HTTP_200_OK
            )
        else:
            return Response(
                {"errors": {"non_field_errors": ["Email or Password is not Valid"]}},
                status=status.HTTP_404_NOT_FOUND,
            )

UserProfileView

class UserProfileView(APIView):
    renderer_classes = [UserRenderer]
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        serializer = UserProfileSerializer(request.user)
        return Response(serializer.data, status=status.HTTP_200_OK)

UserChangePasswordView

class UserChangePasswordView(APIView):
    renderer_classes = [UserRenderer]
    permission_classes = [IsAuthenticated]

    def post(self, request, format=None):
        serializer = UserChangePasswordSerializer(
            data=request.data, context={"user": request.user}
        )
        serializer.is_valid(raise_exception=True)
        return Response(
            {"msg": "Password Changed Successfully"}, status=status.HTTP_200_OK
        )

SendPasswordResetEmailView

class SendPasswordResetEmailView(APIView):
    renderer_classes = [UserRenderer]

    def post(self, request, format=None):
        serializer = SendPasswordResetEmailSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(
            {"msg": "Password Reset link send. Please check your Email"},
            status=status.HTTP_200_OK,
        )

UserPasswordResetView

class UserPasswordResetView(APIView):
    renderer_classes = [UserRenderer]

    def post(self, request, uid, token, format=None):
        serializer = UserPasswordResetSerializer(
            data=request.data, context={"uid": uid, "token": token}
        )
        serializer.is_valid(raise_exception=True)
        return Response(
            {"msg": "Password Reset Successfully"}, status=status.HTTP_200_OK
        )

解决方案

Swagger不显示参数的核心原因是:drf-yasg无法自动识别APIView/GenericAPIView中未显式关联的序列化器元数据,需要通过swagger_auto_schema装饰器手动绑定请求体和参数。

1. 为GenericAPIView类补充序列化器绑定

对于继承GenericAPIView的视图,先指定serializer_class,再配合装饰器:

class UserRegistrationView(GenericAPIView):
    renderer_classes = [UserRenderer]
    serializer_class = UserRegistrationSerializer  # 显式指定序列化器

    @swagger_auto_schema(request_body=UserRegistrationSerializer)
    def post(self, request, format=None):
        serializer = self.get_serializer(data=request.data)  # 改用get_serializer方法
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        token = get_tokens_for_user(user)
        return Response(
            {"token": token, "msg": "Registration Successful"},
            status=status.HTTP_201_CREATED,
        )

2. 为APIView类显式指定请求体

对于继承APIView的视图,必须用swagger_auto_schema手动指定request_body:

class UserLoginView(APIView):
    renderer_classes = [UserRenderer]

    @swagger_auto_schema(request_body=UserLoginSerializer)
    def post(self, request, format=None):
        serializer = UserLoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # ... 后续代码不变

3. 为带路径参数的视图补充参数定义

比如UserPasswordResetView包含uid和token路径参数,需要手动声明:

from drf_yasg import openapi

class UserPasswordResetView(APIView):
    renderer_classes = [UserRenderer]

    @swagger_auto_schema(
        request_body=UserPasswordResetSerializer,
        manual_parameters=[
            openapi.Parameter('uid', openapi.IN_PATH, description="用户ID", type=openapi.TYPE_STRING),
            openapi.Parameter('token', openapi.IN_PATH, description="重置令牌", type=openapi.TYPE_STRING)
        ]
    )
    def post(self, request, uid, token, format=None):
        # ... 后续代码不变

4. 检查序列化器字段定义

确保你的序列化器(比如UserRegistrationSerializer)中明确定义了所有需要展示的字段,例如:

class UserRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(style={'input_type':'password'}, write_only=True)
    password2 = serializers.CharField(style={'input_type':'password'}, write_only=True)
    class Meta:
        model = User
        fields = ['email', 'name', 'password', 'password2']

内容的提问来源于stack exchange,提问作者muyiwa. py

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:35:31