How does one properly create a customized Swagger Schema in the Django Rest Framework?
Asked Answered
M

1

10

I am having trouble creating a customizable swagger schema in the Django Rest Framework. I have read pages of documentation, but have not found a clear cut example on how to generate swagger annotations in python.

I am aware that swagger/schema documentation is readily generated when using ViewSets in Django. However, I am solely using APIViews and want to write a customized schema. I have tried creating a CoreAPI schema but am unaware of how to implement it. I am enclosing some of my sample code and some screenshots as well. The screen shots go from what I have to what I want.

Sample code:

urls.py

from django.conf.urls import url, include
from rest_framework.urlpatterns import format_suffix_patterns
from Views import SampleView as sv
from rest_framework_swagger.views import get_swagger_view
from rest_framework.documentation import include_docs_urls
from rest_framework.renderers import CoreJSONRenderer
from rest_framework.schemas import get_schema_view

schema_view enter code here= get_swagger_view(
    title='Sample API')

urlpatterns = [
    url(r'^sample/$', pv.SampleList.as_view()),
    url(r'^sample/(?P<id>[a-f\d]{24})/$', sv.SampleDetail.as_view()),
    url('^schema/$', schema_view),
]

urlpatterns = format_suffix_patterns(urlpatterns)

views.py

from rest_framework.views import APIView
from Manager.SampleManager import SampleManager as sm

_sampleManager = sm()

class SampleList(APIView):
"""
get:
Return a list of all the existing samples.

post:
Create a new sample.
"""
def get(self, request, format=None):
    
    return _sampleManager.getAll()


def post(self, request,  format=None):
    
    return _sampleManager.create( request)


 class SampleDetail(APIView):
   """
   get:
   Get a sample.

   put:
   Update a sample.

   delete:
   Delete a sample.
   """
def get(self, request, id, format =None):
    return _sampleManager.getById( id)

def put(self, request, id, format =None):

    return _sampleManager.update( request, id)
    
def delete(self, request, id, format =None):
    
    return _sampleManager.deleteById( id)

Serializers.py

from rest_framework_mongoengine.serializers import DocumentSerializer
from .modles import Sample, SampleInner
from Serializers.SampleInnerSerializer import SampleInnerSerializer

class SampleSerializer(DocumentSerializer):
    other = SampleInnerSerializer(many=True)
    class Meta:
        model = Sample
        fields = '__all__'
    
    def create(self, validated_data):
        samples = validated_data.pop('other')
        created_instance = super(SampleSerializer,     self).create(validated_data)

        for sample_data in samples:
            created_instance.other.append(SampleInner(**sample_data))

        created_instance.save()
        return created_instance

    def update(self, instance, validated_data):
        samples = validated_data.pop('other')
        updated_instance = super(SampleSerializer, self).update(instance, validated_data)

        for sample_data in samples:
            updated_instance.other.append(SampleInner(**sample_data))

        updated_instance.save()
    return updated_instance

Schema.py

import coreapi
from rest_framework.decorators import api_view, renderer_classes
from rest_framework import renderers, response

schema = coreapi.Document(
 title='Sample API',
 content={
     'sample': coreapi.Link(
         url='/sample/',
         action='post',
         fields=[
             coreapi.Field(
                name='from',
                required=True,
                location='query',
                description='City name or airport code.'
            ),
            coreapi.Field(
                name='to',
                required=True,
                location='query',
                description='City name or airport code.'
            ),
            coreapi.Field(
                name='date',
                required=True,
                location='query',
                description='Flight date in "YYYY-MM-DD" format.'
            )
        ],
        description='Create partner'
    )
   }
 )

@api_view()
@renderer_classes([renderers.CoreJSONRenderer])
def schema_view(request):
    return response.Response(schema)

enter image description here

enter image description here

enter image description here

enter image description here

Metaplasia answered 13/3, 2017 at 19:36 Comment(4)
That is too much of information. Let's discuss about one API and issues with it's documentation. Can you please update the question accordingly?Madalynmadam
Did anyone found a solution to this? I am stuck with the same problem.Cnemis
Its impossible, I eventually gave up on this and used github.com/lord/slateMetaplasia
Guys check my answer.Letter
L
0

There is two solution for you in this senario, One "go with the GenricApiView" Two "Create Custom row Schema" let's go with -- >solution one.

urls.py

schema_view = get_swagger_view(title='Test All API')
urlpatterns = [
 
   path('swagger2/', schema_view),
]

view.py

class LoginAPIView(generics.GenericAPIView):
    serializer_class = LoginSerializer
    permission_classes = [permissions.AllowAny]

    def post(self, request):

        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

Result

enter image description here

--> Solution two:

urls.py configuration is same as before

views.py

class BlacklistTokenAdding(APIView):
    permission_classes = [permissions.AllowAny]

    schema = ManualSchema(fields=[
        coreapi.Field(
            "first_field",
            required=True,
            location="body",
            schema=coreschema.String()
        ),
        coreapi.Field(
            "second_field",
            required=True,
            location="body",
            schema=coreschema.String()
        ),
    ])

    def post(self, request, format='json'):
        try:
            refresh_token = request.data["refresh_token"]
            token = RefreshToken(refresh_token)
            token.blacklist()
            return Response(status=status.HTTP_200_OK)
        except Exception as e:
            return Response(status=status.HTTP_400_BAD_REQUEST)

//Note the first_field & second_field is to demonstration you can add here as much field as you want. Result

enter image description here

Letter answered 17/2, 2022 at 7:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.