Skip to content

DRF – YASG Customization

Part 8 of 8 in the series Django REST Framework




In last post, we created browsable API based on swagger for our Django REST Framework APIs using YASG library. In this post, we will continue to improve the API documentation using YASG Customization features.

You can download the code for this example from here : https://github.com/hpin2019/coding-sessions/tree/master/drf-tutorial-2

YASG GET and POST calls customization

Go ahead and change your views.py for our quotes app as below :

from quotes.models import Quote
from quotes.serializers import QuoteSerializer
from django.http import Http404

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

#For yasg
from drf_yasg.utils import swagger_auto_schema



class QuoteList(APIView):
    '''
    List all quotes or create a new quote
    '''
    @swagger_auto_schema(
        responses={200: QuoteSerializer(many=True),
                   401: 'Unauthorized',
                   404: 'No quotes found'},
        tags=['Get Quotes'],
        operation_description="Method to fetch all the quotes",
    )
    def get(self,request,format=None):
        print("Get quotes list called")
        quotes = Quote.objects.all()
        serializer = QuoteSerializer(quotes, many=True)
        return Response(serializer.data)

    @swagger_auto_schema(
        description="Method to post a new building",
        request_body=QuoteSerializer,
        responses={200: QuoteSerializer(many=False),
                   401: 'Unauthorized',
                   201: 'Quote Added'},
        tags=['Create, Update and Delete Quote'],
        operation_description="Method to post a new Quote",
    )
    def post(self, request, format=None):
        print("Create quote called")
        serializer = QuoteSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Here’s the summary of what we have added :

  1. Imported swagger_auto_schema using :
    from drf_yasg.utils import swagger_auto_schema
  2. For get and post method in our QuoteList class, we added yasg decorator @swagger_auto_schema with few inputs like request_body, responses, tags and operation_description.

Now let’s see how it looks in browser.

You can see that GET api is now categorized under “Get Quotes” as we have added that tag in our documentation and Similarly POST api is now categorized under “Create, Update and Delete Quote”. Since we have not changed QuoteDetail class, other APIs are not yet categorized.

Also, now you can see “Quote” model at the end in Models section. If we have many models in our APIs, all will start showing up at the end for easy browsing. This is due to the inclusion of “QuoteSerializer” class in our description.

Now, let’s see how GET and POST api looks like.

As you can see, GET call’s description is now updated and also Response model clearly shows what will the response output. Our quote model is shown with details using QuoteSerializer class. Also, 401, 404 method error details are also shown as per our description.

Next is POST call.

Here also, Method description, Request object and Response object are now showing. Also, when you click “Try it out” button, input text area has Quote object already included, so you can change the input details easily.

YASG POST, PUT and DELETE Customization

Similarly, you can update QuoteDetail class to include more details and improve the documentation. Below is one such example.

class QuoteDetail(APIView):
    """
    Retrieve, update or delete a quote instance.
    """
    @swagger_auto_schema(
        auto_schema=None,
    )
    def get_object(self, pk):
        try:
            return Quote.objects.get(pk=pk)
        except Quote.DoesNotExist:
            raise Http404

    @swagger_auto_schema(
        responses={200: QuoteSerializer(many=True),
                   401: 'Unauthorized',
                   404: 'No quote found for the given id'},
        tags=['Get Quotes'],
        operation_description="Method to fetch a quote",
    )
    def get(self, request, pk, format=None):
        quote = self.get_object(pk)
        serializer = QuoteSerializer(quote)
        return Response(serializer.data)

    @swagger_auto_schema(
        description="Method to update a quote",
        request_body=QuoteSerializer,
        responses={200: QuoteSerializer(many=True),
                   401: 'Unauthorized',
                   201: 'Quote updated'},
        tags=['Create, Update and Delete Quote'],
        operation_description="Method to update a quote",
    )
    def put(self, request, pk, format=None):
        quote = self.get_object(pk)
        serializer = QuoteSerializer(quote, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    @swagger_auto_schema(
        description="Method to delete a quote",
        request_body=QuoteSerializer,
        responses={200: QuoteSerializer(many=True),
                   401: 'Unauthorized',
                   201: 'Quote deleted'},
        tags=['Create, Update and Delete Quote'],
        operation_description="Method to update a quote",
    )    
    def delete(self, request, pk, format=None):
        quote = self.get_object(pk)
        quote.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

And output based on above changes :

As you can see, all GET apis are now under “Get Quotes” category and all other APIs are under second category. For more customization options, check the yasg documentation by clicking here.

This is the last post in this series. Hope this is helpful to you. For any comments/suggestions, please provide your input in comments section and subscribe to our mailing list to keep getting new stuff.

Series Navigation<< DRF – Browsable API
Published inDjangoDjango REST FrameworkPython

3 Comments

  1. I enjoy the knowledge on your website. Many thanks!

  2. Keep up the outstanding work !! Lovin’ it!

  3. You’re a very beneficial website; could not make it without ya!

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: