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

5πŸ‘

βœ…

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.

πŸ‘€opalczynski

29πŸ‘

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)
πŸ‘€Aneesh R S

2πŸ‘

A working example for a custom ViewSet, with django-rest-swagger==2.2.0:

from rest_framework import viewsets
from rest_framework.schemas import AutoSchema
from rest_framework.compat import coreapi, coreschema
from rest_framework.decorators import action


class DeviceViewSchema(AutoSchema):
    """
    Schema customizations for DeviceViewSet
    """

    def get_manual_fields(self, path, method):
        extra_fields = []
        if path.endswith('/send_command/'):
            extra_fields = [
                coreapi.Field(
                    "command",
                    required=True,
                    location="form",
                    schema=coreschema.String()
                ),
                coreapi.Field(
                    "params",
                    required=False,
                    location="form",
                    schema=coreschema.String()
                ),
            ]
        manual_fields = super().get_manual_fields(path, method)
        return manual_fields + extra_fields


class DeviceViewSet(viewsets.ViewSet):
    lookup_field = 'channel'
    lookup_value_regex = '[\w-]+'

    schema = DeviceViewSchema()

    @action(methods=['post'], detail=True, url_name='send_command')
    def send_command(self, request, channel):
        """
        Send command to device

        Parameters:
        - command: string
        - params: string (JSON encoded list or dict)
        """
        ...

The final result is:

enter image description here

πŸ‘€Mario Orlandi

Leave a comment