Surya Bhusal
Surya Bhusal

Reputation: 650

How to add the serializer sample response with custom response parameter in drfyasg swagger docs?

ViewSet

class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginSerializer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data

        # Generate user token
        _, token = AuthToken.objects.create(user)
        
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": token
        })

As in the above viewset i've added custom field token added as a custom field manually. But it's not showing in swagger docs.

What I've tried

from rest_framework import status
from drf_yasg import openapi

from authprofile.serializers import UserSerializer

login_response_schema = {
        status.HTTP_201_CREATED: openapi.Response(
            description="User Created",
            examples= {
                "application/json":{
                    "user":UserSerializer,
                    "token": "<Token>",
                }
            }
        )
}

class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginSerializer

    @swagger_auto_schema(operation_description="Login with email and password", \
        responses=login_response_schema)
    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data

        # Generate user token
        _, token = AuthToken.objects.create(user)

        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": token
        })

Doing so gives me error saying:

TypeError: Object of type 'SerializerMetaclass' is not JSON serializable

Upvotes: 2

Views: 1525

Answers (1)

NetrobeWebby
NetrobeWebby

Reputation: 116

Code in serializers.py file

class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField(required=True)
    password = serializers.CharField(write_only=True, required=True)

    def validate(self, attrs):
        # Get required info for validation
        email = attrs['email']
        password = attrs['password']

        """
        Check that the email is available in the User table
        """
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            raise serializers.ValidationError({"email": 'Details do not match an active account'})
        
        if not user.check_password(password):
            raise serializers.ValidationError({"password": 'Your password is incorrect'})

        return attrs

The below will be used to format the response sample shown in swagger

class LoginResponseSerializer200(serializers.Serializer):
    user = UserSerializer()
    tokens = JWTTokenResponseSerializer()

Code in views.py file

class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginSerializer

    @swagger_auto_schema(
        request_body=serializers.LoginSerializer,
        responses={
            200: LoginResponseSerializer200
        }
    )
    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data

        # Generate user token
        _, token = AuthToken.objects.create(user)
        
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": token
        })

Upvotes: 0

Related Questions