Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I specify the parameter for POST requests while using APIView with django-rest-swagger

In the latest version on Django REST Swagger (2.1.0) YAML docstrings have been deprecated. I cannot get swagger to show the POST request parameters.

Here is my view

class UserAuthenticationView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = UserAuthenticationSerializer(data=self.request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            return Response({'token': user.auth_token.key}, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)

Here is my Serializer

class UserAuthenticationSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        if username and password:
            user = authenticate(username=username, password=password)
            if user:

                if not user.is_active:
                    msg = 'User account is disabled.'
                    raise serializers.ValidationError(msg, code='authorization')

            else:
                msg = 'Unable to log in with provided credentials.'
                raise serializers.ValidationError(msg, code='authorization')

        else:
            msg = 'Must include "username" and "password".'
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        return attrs

This is what I get in my generated enter image description here

I do not get a form with the fields for the POST data. How do I get that?

like image 542
utkbansal Avatar asked Dec 12 '16 15:12

utkbansal


People also ask

Is Django rest Swagger deprecated?

This project is no longer being maintained. Please consider drf-yasg as an alternative/successor.

What's the difference between ViewSet & APIView in Django?

APIView is the base class based view. Viewsets have APIView as a parent class. With Viewsets, you code more specific methods . For example the 'retrieve' method, will expect arguments of the request and the pk of the object to be retrieved.


2 Answers

django-rest-swagger uses rest_framework.schemas.SchemaGenerator to generate the schema and SchemaGenerator uses get_serializer_fields to get the serializer information of a view. get_serializer_fields checks if a view has a get_serializer method to generate the form. GenericAPIView provides the get_serializer so inheriting from it is enough.

Inherit view from GenericAPIView rather than simple APIView. And add serializer_class attribute with appropriate serializer

from rest_framework.generics import GenericAPIView 

class UserAuthenticationView(GenericAPIView):

    serializer_class = UserAuthenticationSerializer

    def post(self, request, *args, **kwargs):
        serializer = UserAuthenticationSerializer(data=self.request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            return Response({'token': user.auth_token.key}, status=status.HTTP_200_OK)    
        return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)
like image 91
Aneesh R S Avatar answered Sep 21 '22 17:09

Aneesh R S


This is the rest framework get schema code (the part of it):

def get_serializer_fields(self, path, method, view):
    """
    Return a list of `coreapi.Field` instances corresponding to any
    request body input, as determined by the serializer class.
    """
    if method not in ('PUT', 'PATCH', 'POST'):
        return []

    if not hasattr(view, 'get_serializer'):
        return []

    serializer = view.get_serializer()

    if isinstance(serializer, serializers.ListSerializer):
        return [
            coreapi.Field(
                name='data',
                location='body',
                required=True,
                type='array'
            )
        ]
...

As you can see - it should work if you define the get_serializer method on your view - which returns the UserAuthenticationSerializer.

-- EDIT --

Forget: Happy Coding.

like image 39
opalczynski Avatar answered Sep 23 '22 17:09

opalczynski