Django API Documentation Using Swagger with drf-yasg

Last updated 4 months ago | 418 views 75     5

Tags:- Python Django DRF

Introduction: Why Swagger API Docs Matter in Django

Great code deserves great documentation—especially for APIs.

When building REST APIs with Django REST Framework (DRF), clear and up-to-date documentation is critical for:

  • Frontend developers and third-party consumers

  • Testing and debugging

  • Onboarding new developers

  • Reducing time wasted explaining endpoints manually

That’s where Swagger (OpenAPI) comes in. With tools like drf-yasg, you can generate interactive, auto-updating Swagger UI right from your Django code.

Let’s walk through setting it up step-by-step. 


⚙️ Step-by-Step Guide to Adding Swagger with drf-yasg

✅ Step 1: Install drf-yasg

Run this command in your Django project environment:

pip install drf-yasg

It stands for Yet Another Swagger Generator—and it’s one of the most popular Swagger tools for DRF.


✅ Step 2: Update INSTALLED_APPS

In your settings.py:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'drf_yasg',
]

✅ Step 3: Configure Swagger URLs

In your main urls.py:

from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from django.urls import path, re_path

schema_view = get_schema_view(
   openapi.Info(
      title="My Project API",
      default_version='v1',
      description="API documentation for My Django project",
      terms_of_service="https://www.example.com/terms/",
      contact=openapi.Contact(email="[email protected]"),
      license=openapi.License(name="BSD License"),
   ),
   public=True,
   permission_classes=[permissions.AllowAny],
)

urlpatterns = [
    # your existing URLs...
    re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

This gives you:

  • http://localhost:8000/swagger/ – interactive Swagger UI

  • http://localhost:8000/redoc/ – elegant ReDoc UI

  • http://localhost:8000/swagger.json – raw OpenAPI spec


✅ Step 4: Annotate Your Views (Optional but Recommended)

To improve the documentation, add descriptions to your views or viewsets:

from rest_framework.decorators import api_view
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

@swagger_auto_schema(
    method='get',
    operation_description="Get a simple hello world message",
    responses={200: openapi.Response("Success")}
)
@api_view(['GET'])
def hello_world(request):
    return Response({"message": "Hello, world!"})

For class-based views or viewsets:

from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    @swagger_auto_schema(operation_description="List all products")
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

✅ Full Working Example

views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

@swagger_auto_schema(
    method='get',
    operation_description="Return a welcome message",
    responses={200: openapi.Response('Success')}
)
@api_view(['GET'])
def welcome(request):
    return Response({"message": "Welcome to the Django API!"})

urls.py

from django.urls import path
from .views import welcome

urlpatterns = [
    path('welcome/', welcome, name='welcome'),
]

project/urls.py

from django.urls import path, re_path, include
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from rest_framework import permissions

schema_view = get_schema_view(
   openapi.Info(
      title="Example API",
      default_version='v1',
      description="Django Swagger API example",
   ),
   public=True,
   permission_classes=[permissions.AllowAny],
)

urlpatterns = [
    path('api/', include('myapp.urls')),
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

⚠️ Tips & Common Pitfalls

✅ Best Practices

  • Always document query parameters using openapi.Parameter.

  • Use swagger_auto_schema to override or enhance default documentation.

  • Keep docstrings short and meaningful.

❌ Common Pitfalls

Problem Solution
Swagger UI returns 403 Set permission_classes=[permissions.AllowAny] in schema view
Endpoints missing from docs Make sure all views are routed via urlpatterns and DRF-compatible
JSON format not accessible Check regex in the Swagger URL route
Errors in schema generation Use swagger_auto_schema(auto_schema=None) to skip problematic views

Conclusion & Best Practices

Using Swagger (via drf-yasg) in Django is a must-have for serious API development. It boosts collaboration, testing, and integration while saving you tons of time.

✅ Key Takeaways:

  • Use drf-yasg for Swagger/OpenAPI documentation in Django.

  • Integrate swagger_auto_schema for better control.

  • Auto-generate docs that stay up to date with your codebase.

  • Offer both Swagger UI and ReDoc for different consumer needs.

"Good APIs are documented. Great APIs are self-documented."