Django Rest Swagger 2 for API Documentation:

This article provides a beginner’s guide to django rest swagger 2 with function based views as well as class based views. It provides building the project from scratch. For those who want to integrate Django Rest Swagger into an existing project, head straight to: Integrating Django Rest Swagger .

Get this full project from its github repository.

Getting Started

Before we start, we need this to be installed:

Project Setup

Start by making the project as in DRF official docs:

mkdir django-rest-swagger-docs
cd django-rest-swagger-docs

Make virtual environment with python3 and activate it:

virtualenv env --python=python3
source ./env/bin/activate

Install Django and DjangoRestFramework:

pip install django
pip install djangorestframework==3.5.3

Note: Installing the correct version of DRF is very important.

Make project named “demo” in current directory and navigate inside it:

django-admin startproject demo .
cd demo

Make two apps cbv-demo (for class based views) and fbv-demo (for function based view) inside demo project,:

django-admin startapp cbv_demo
django-admin startapp fbv_demo

Get back to main directory:

cd ..

Now sync database and create database user:

python manage.py migrate
python manage.py createsuperuser

Making class based views:

Make a simple model at demo/cbv_demo/models.py with code below:

View this full project on github

Make a simple serializer at demo/cbv_demo/serializers.py with code below:

View this full project on github

Make a simple view at demo/cbv_demo/views.py with code below:

View this full project on github

Add urls of this app to demo/cbv_demo/urls.py as:

View this full project on github

Making function based views:

Make a simple model at demo/fbv_demo/models.py with code below:

View this full project on github

Make a simple view at demo/fbv_demo/views.py with code below:

View this full project on github

Add urls of this app to demo/fbv_demo/urls.py as:

View this full project on github

Integrating together:

Add ‘rest_framework’ and both apps to demo/settings.py as:

View this full project on github

Now add urls of both apps to demo/urls.py:

View this full project on github

Now you have two class based views (GET, POST) in demo/cbv_demo/views.py and two function based views in demo/fbv_demo/views.py .

In order to run it, apply migrations to make tables in db against models and runserver to test:

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Integrating Django Rest Swagger:

In order to integrate django-rest-swagger, first install it through pip as:

pip install django-rest-swagger==2.1.1

Note: Installing the correct version is very important.(This one works best with djangorestframework==3.5.3)

Add it into the demo/settings.py as:

View this full project on github

Using get_swagger_view the shortcut method:

Make swagger schema view in demo/urls.py and assign it a url as :

View this full project on github

Your swagger should run at: http://127.0.0.1:8000/swagger/

Using shortcut method can let us into following issues:

  • No way to document parameters of function based views
  • Less customizablity
  • No way to enforce permission classes
  • No handy way to exclude swagger view from schema

In order to acheive these functionalities, we ll go for its advance usage.

Advance Usage:

For finer control and to make swagger more customizable we write swagger schema view manually and to document parameters for function based views, we override SchemaGenerator of rest_framework which is used by django-rest-swagger (version 2) to generate documentation.

Create a file demo/swagger_schema.py and add following code to it:

View this full project on github
exclude_from_schema = True removes the swagger view from schema.
CustomSchemaGenerator class overrides the default DRF SchemaGenerator so that it first checks if the view has .__doc__ inside it, if available it uses this YAML to make parameter fields, otherwise it looks for serializers. So in this way we acheive the functionality of Django Rest Swagger (version 1) which supported YAML docstrings as well.
SwaggerSchemaView is the view made for swagger, which calls CustomSchemaGenerator to create the schema instead of default SchemaGenerator.

Now, You ll need to install yaml as:

pip install PyYAML

Next change demo/urls.py to point swagger url to this SwaggerSchemaView as:

View this full project on github

Defining parameters in FBV using YAML:

Now add __doc__ to the function based API by adding YAML into it, add following YAML to save_medical in demo/fbv_demo/views.py as:

View this full project on github
Now CustomSchemaGenerator will be able to read this YAML and create input parameters against it accordingly.

Go to swagger url : http://127.0.0.1:8000/swagger/

You will be able to see input parameters fields for save_medical POST API as well.

Customize Swagger UI:

Swagger UI can be customized to some extent, which is sufficient for a normal user, Follow these simple steps:

  • Make the file as demo/templates/rest_framework_swagger/index.html and add following code to it:
View this full project on github
This will override the tag {% block header %}, for the sample we are just changing the color of header, rest remains the same.
  • Set template directory in demo/settings.py as:
View this full project on github

You ll be able to see custom BLACK header at http://127.0.0.1:8000/swagger/.

Some add-ons that may help:

Django Rest Swagger provide much customization, most of which is explained indepth in its Official Doc .

Few mostly used customization is explained here for ease. Add SWAGGER_SETTINGS in demo/settings.py to provide custom settings:

Swagger Login methods:

You can login to swagger by using button Authorize in the header of swagger UI. In order to use django superuser username and password to login use:

SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'basic': {
'type': 'basic'
}
},
}

In order to use authentication token to login to swagger use:

SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
"api_key": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
},
}

You can use oauth2 for security. Details: security definitions .

Customize format of parameters defined in DOCSTRING:

You can customize YAML parameters, the most important is location that helps you with passing the data to API in different forms.

  • location: form , to access data as request.POST['key']
  • location: body , to access data as request.body , you may have to add JSON_EDITOR: False in SWAGGER_SETTINGS in demo/settings.py.
  • location: query , to access data as request.GET['key']

Other location options include location: post and location: path

Common issues and their solution:

Since the release of version 2 of django-rest-swagger, various issues arise because this version is fundamentally different from previous versions, i.e. DOCSTRING has been deprecated by DRF and now swagger uses DRF ‘s SchemaGenerator to generate schema.

Here are some of the reported issues and their possible solution:

  • The schema generator did not return a schema Document: All the APIs of your project may be authentication protected, try removing authentication from few of them.
  • Input parameters for class based views do not appear: You might be using APIView for making class based views. Try using generics.GenericAPIView to make APIs. All the views must have serializer or Docstring __doc__.
  • Input parameters for function based views do not appear: You might be using incompatible versions, try using djangorestframework==3.5.3 and django-rest-swagger==2.1.1. In order to use other versions you may need to modify get_link inside demo/swagger_schema.py.
  • TypeError: ‘type’ object is not iterable: Try adding your authentication in this format @permission_classes((IsAuthenticated, ))
  • Invalid block tag: ‘static’, expected ‘endblock’. Did you forget to register or load this tag? : Try adding {% load staticfiles %} to the overridden block of swagger UI e.g. add in demo/templates/rest_framework_swagger/index.html as:
{% extends "rest_framework_swagger/base.html" %}
{% block header %}
<div id='header' style="background-color: #000000;">
<div class="swagger-ui-wrap">
{% load staticfiles %}
...
...
</div>
</div>
{% endblock %}

End Note:

This article is a little effort to help those who are facing issues using django-rest-swagger 2. If you like this effort, please like and share this with others. If you have any suggestions, comment here or approach me on linkedin, github, twitter or send me an email to discuss in person. I would love to hear from you.