Schemas & OpenAPI
API schemas are a useful tool that allow for a range of use cases, including generating reference documentation, or driving dynamic client libraries that can interact with your API.
WARNING
Deprecation Notice: DRF's built-in support for generating OpenAPI schemas is deprecated in favor of 3rd party packages. The built-in support will be moved into a separate package and subsequently retired. We recommend using drf-spectacular.
However, understanding the built-in system is still helpful as many concepts carry over. DRF natively supports OpenAPI (formerly Swagger), which is a widely adopted standard for describing APIs.
Schema Generation Process
Before generating schemas, it's important to understand the components involved. Schema generation in DRF has several moving parts:
SchemaGenerator: The top-level class responsible for walking your configured URL patterns, findingAPIViewsubclasses, enquiring for their schema representation and compiling the final schema object.AutoSchema: Encapsulates all the details necessary for per-view schema introspection. It is attached to each view via theschemaattribute.generateschema: A management command that allows you to generate a static schema offline.SchemaView: A view that dynamically generates and serves your schema.
Generating an OpenAPI Schema
::: Prerequisites To generate schemas, you must install additional dependencies: pip install pyyaml uritemplate inflection.
pyyaml: Generates schema into YAML format.uritemplate: Gets parameters in path.inflection: Pluralizes operations appropriately. :::
Static vs Dynamic Generation
You can generate your schema statically (to a file) or dynamically (via an endpoint). Generating statically is often preferred for CI/CD pipelines, while dynamic generation is useful if your schema depends on database values.
# Generate a YAML file (default)
python manage.py generateschema --file openapi-schema.yml
# Or explicitly format as JSON
python manage.py generateschema > schema.json --format jsonfrom django.urls import path
from rest_framework.schemas import get_schema_view
# In your urls.py
urlpatterns = [
path('openapi/', get_schema_view(
title="Your Project",
description="API for all things …",
version="1.0.0"
), name='openapi-schema'),
]When a user visits /openapi/, they will receive a YAML (or JSON, based on negotiation) representation of the OpenAPI schema. By default, get_schema_view() uses settings.DEFAULT_AUTHENTICATION_CLASSES and settings.DEFAULT_PERMISSION_CLASSES.
Customizing Schema Generation
You can customize how individual views generate their schema operations by setting the schema attribute on a view to an instance of AutoSchema (or a subclass).
from rest_framework.views import APIView
from rest_framework.schemas.openapi import AutoSchema
class CustomView(APIView):
# Customize the schema for this specific view
schema = AutoSchema(
tags=['Users'],
operation_id_base='CustomUser',
)TIP
Excluding Views: To entirely exclude a view from the schema, you can set its schema attribute to None. This is useful for internal endpoints or administrative views you don't want exposed in public documentation.
class ExcludedView(APIView):
schema = NoneThird-Party Packages (Recommended)
While DRF includes basic OpenAPI support, you should use third-party packages for a fully-featured Swagger UI or ReDoc interface, especially given the deprecation of the built-in generator.
A popular and highly recommended choice is drf-spectacular:
- Install it:
pip install drf-spectacular - Add to
INSTALLED_APPS:'drf_spectacular' - Set it as the default schema class in settings:
# settings.py
REST_FRAMEWORK = {
# Replaces the default AutoSchema with drf-spectacular's implementation
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}Then you can use it to serve Swagger UI or ReDoc directly:
from django.urls import path
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
urlpatterns = [
# The actual schema endpoint
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
# The Swagger UI endpoint that consumes the schema
path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
]