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
相关产品推荐
相关产品推荐

