It seems like django-rest-swagger dropped support for the YAML documentation, and replaced it with a vague non-documented way to do things. I've spent the last 48 hours trying to understand how I can have it document the parameters that go into my post methods.
For instance: I have this:
class user_addresses(APIView):
"""
get all addresses or post a new one
"""
authentication_classes = ([JSONWebTokenAuthentication])
def get(self, request, format=None):
addresses = Address.objects.filter(owner_id=request.user.id)
print (addresses)
serializer = address_serializer(addresses, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = address_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'success': True,
'result': serializer.validated_data},
status=status.HTTP_201_CREATED)
return Response({'success': False,
'result': serializer.errors},
status=status.HTTP_400_BAD_REQUEST)
But the django-rest-swagger will show it as:
Can someone point me in the direction of something that works where I can define all the rich data that swagger allows, like the post field names, if they're mandatory or not. etc. i'm just going crazy here running in circle and can't find anything but complaints that there's no way to do this.
Django REST Swagger: deprecated (2019-06-04) This project is no longer being maintained.
Update settings.py file in main Django project to load django-rest-swagger app. Update urls.py file in main Django project to first load the get_swagger_view utility function and then add path to route to Swagger UI view. This is where the first hiccup rears it's head.
Django REST framework provides the capability to build RESTful (Representational State Transfer) kind of APIs with the Django framework. Swagger UI allows us to build our documentation in the form of HTML pages so it can be viewed and read with ease.
Django Rest Framework + Swagger from rest_framework import routers from yourapp.accounts. views import UserViewSet router = routers. DefaultRouter() router. register(r'users', UserViewSet) urlpatterns = [ url(r'^api/v1/', include(router.
So the idea with the 2.0 update was to use CoreAPI, the "internal" rest framework schema generation, and from it generate the swagger spec.
CoreAPI uses serializer and view classes to do its thing. From serializers it knows what fields are required, what type are those fields and if you want to add your personal description you can do so with help_text
parameter:
some_field = serializers.Field(help_text='Field description')
In your case, the problem will be that it won't be able to understand the relationship between the APIView
and your serializer. I suggest to take an extra step and move to generic views or viewsets, all of them support serializer_class
attribute that can be used for the introspection. For your example something like this should work:
# serializer
class AddressSerializer(serializers.ModelSerializer):
line1 = serializers.CharField(help_text='Field documentation!')
class Meta:
model = Address
fields = '__all__'
read_only_fields = 'owner',
def create(self, validated_data):
validated_data['owner'] = self.context['request'].user
return super().create(validated_data)
# api class-based view
class UserAddresses(generics.ListCreateAPIView):
"""
General API documentation (not wisible in the swagger view)
get:
GET-specific documentation!
Lorem ipsum
post:
POST-specific documentation!
Dolor **sit amet**
"""
authentication_classes = ([JSONWebTokenAuthentication])
permission_classes = permissions.IsAuthenticated,
serializer_class = AddressSerializer
def get_queryset(self):
return Address.objects.filter(owner_id=self.request.user.id)
For views there is a specific docstirng format, it's very simple and hopefully, will improve overtime. In any way, you should have a bit more acceptable result now:
A CoreAPI Document can help you make a custom Swagger view. Swagger takes a coreapi json input to render the view - Django Rest Swagger uses the Python bindings of CoreAPI to generate that JSON (https://github.com/core-api/python-client).
coreapi.Document
object contain?For each API, you can create a coreapi.Link()
object.
Each Link
object contains:
The list of fields must contain coreapi.Field()
objects. A Field
object has the parameters:
A sample Swagger Schema would look something like this, if we were to use CoreAPI:
import coreapi
def api_schema_generator():
api_schema = coreapi.Document(
title="My Swagger",
content={
"User Addresses": {
"int_api_get": coreapi.Link(
url="/int_api/v1/addresses/",
action="get",
description="Get addresses of a user",
fields=[
coreapi.Field(
name="user_id",
required=True,
location="path",
description="Unique ID of the user whose addresses are to be found"
),
]
),
"int_api_post": coreapi.Link(
url="/int_api/v1/addresses/",
action="post",
description="Add address for a user",
fields=[
coreapi.Field(
name="user_id",
required=True,
location="path",
description="Unique ID of the user"
),
coreapi.Field(
name="address",
required=True,
location="path",
description="Address of the user"
),
]
)
}
}
)
return api_schema
Our view would take this coreapi.Document
object as input. We use the SwaggerUIRenderer
, OpenAPIRenderer
and CoreJSONRenderer
decorators for our view.
views.py:
from rest_framework.decorators import api_view, renderer_classes
from rest_framework_swagger import renderers as swagger_renderer
from rest_framework import renderers
@api_view()
@renderer_classes([renderers.CoreJSONRenderer,
swagger_renderer.OpenAPIRenderer,
swagger_renderer.SwaggerUIRenderer,
])
def schema_view(request):
api_schema = api_schema_generator()
return response.Response(api_schema)
All that we need now is a URL mapping for our view.
urls.py:
from django.conf.urls import include, url
urlpatterns = [
url(r'^$', views.schema_view),
]
Writing a custom swagger might seem slightly tedious, but you have complete control over what data you want to expose in your Swagger View.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With