drf_yasg @swagger_auto_schema not showing the required parameters for POST Request

Question:

I am using django-yasg to create an api documentation. But no parameters are showing in the documentation to create post request. Following are my codes:
After that in swagger api, no parameters are showing for post request to create the event
enter image description here

model.py

class Events(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    category = models.ForeignKey(EventCategory, on_delete=models.CASCADE)
    name = models.CharField(max_length=250, null=True)
    posted_at = models.DateTimeField(null=True, auto_now=True)
    location = models.CharField(max_length=100, null=True)
    banner = models.ImageField(default='avatar.jpg', upload_to='Banner_Images')
    start_date = models.DateField(
        auto_now=False, auto_now_add=False, blank=True, null=True)
    end_date = models.DateField(
        auto_now=False, auto_now_add=False, blank=True, null=True)
    description = models.TextField(max_length=2000, null=True)
    completed = models.BooleanField(default=False)

    def __str__(self):
        return f'{self.name}'

    class Meta:
        verbose_name_plural = "Events"

serializers.py

class EventSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True, many=False)
    category = EventCategorySerializer(read_only=True, many=False)

    class Meta:
        model = Events
        fields = '__all__'

views.py

@api_view(['POST'])
@permission_classes([IsAuthenticated])
@user_is_organization
@swagger_auto_schema(
    request_body=EventSerializer
)
def registerEvent(request):
    """
        To Register an events, you must be an organization
    """
    data = request.data
    print("==================")
    print(data)
    print("==================")
    try:
        Event = Events.objects.create(
            user = request.user,
            category=EventCategory.objects.get(category=data['category']),
            name=data['name'],
            location=data['location'],
            start_date=data['start_date'],
            end_date=data['end_date'],
            description=data['description'],
            completed=data['completed'],
        )
        serializer = EventSerializer(Event, many=False)
        Event = Events.objects.get(id=serializer.data['id'])
        Event.banner = request.FILES.get('banner')
        Event.save()
        serializer = EventSerializer(Event, many=False)
        return Response(serializer.data)
    except:
        message = {'detail': 'Event with this content already exists'}
        return Response(message, status=status.HTTP_400_BAD_REQUEST)
Asked By: Nirajan Bekoju

||

Answers:

can you modify your swagger_auto_schema decorator like this?

@swagger_auto_schema(
    methods=['post',],
    request_body=EventSerializer )
Answered By: Nova

I got it running with following changes in views.py

@swagger_auto_schema(
    methods=['post'],
    request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['category','name', 'location', 'start_date', 'end_date', 'description', 'completed', 'banner'],
        properties={
            'category':openapi.Schema(type=openapi.TYPE_STRING),
            'name':openapi.Schema(type=openapi.TYPE_STRING),
            'location':openapi.Schema(type=openapi.TYPE_STRING),
            'start_date':openapi.Schema(type=openapi.TYPE_STRING, default="yyyy-mm-dd"),
            'end_date':openapi.Schema(type=openapi.TYPE_STRING, default='yyyy-mm-dd'),
            'description':openapi.Schema(type=openapi.TYPE_STRING), 
            'completed':openapi.Schema(type=openapi.TYPE_BOOLEAN, default=False),
            'banner': openapi.Schema(type=openapi.TYPE_FILE),
        },
    ),
    operation_description='Create an events' 
)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
@user_is_organization
def registerEvent(request):
    """
        To Register an events, you must be an organization
    """
    data = request.data
    print("==================")
    print(data)
    print(type(data))
    category=EventCategory.objects.get(category=data['category']),
    print(category)
    print(type(data["start_date"]))
    print("==================")
    try:
        Event = Events.objects.create(
            user = request.user,
            category=EventCategory.objects.get(category=data['category']),
            name=data['name'],
            location=data['location'],
            start_date=data['start_date'],
            end_date=data['end_date'],
            description=data['description'],
            completed=data['completed'],
        )
        print("****************************")
        serializer = EventSerializer(Event, many=False)
        Event = Events.objects.get(id=serializer.data['id'])
        Event.banner = request.FILES.get('banner')
        Event.save()
        serializer = EventSerializer(Event, many=False)
        return Response(serializer.data)
    except ValidationError as e:
        return Response({"ValidationError" : e}, status = status.HTTP_400_BAD_REQUEST)
    except Exception as e:
        message = {'error': e}
        return Response(message, status=status.HTTP_400_BAD_REQUEST)

enter image description here

Answered By: Nirajan Bekoju

All you need to do is place the @swagger_auto_schema on the top. To help it display the parameters create a serializer for it. This way, you only have to change the serializer in the future keeping everything in one place.

API view

@swagger_auto_schema(request_body=serializers.RequestSerializer, method='post')
@api_view(http_method_names=['POST'])
def special_get(request):
    data = JSONParser().parse(request)
    unique_id = data.get("unique_id", "")
    ... 

Serializer.py

class RequestSerializer(serializers.Serializer):
    unique_id = serializers.CharField(max_length=50, allow_null=False, allow_blank=True)
    sentence_list = serializers.ListField(
        child=serializers.CharField(allow_blank=False, trim_whitespace=True)
    )
Answered By: Shashank Yadav