django-rest-framework/api-guide/schemas/index.html

3357 lines
72 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Django REST framework - Web APIs for Django">
<link rel="canonical" href="https://www.django-rest-framework.org/api-guide/schemas/">
<link rel="prev" href="../metadata/">
<link rel="next" href="../format-suffixes/">
<link rel="icon" href="../../theme/img/favicon.ico">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.0">
<title>Schemas - Django REST framework</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.618322db.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../theme/stylesheets/extra.css">
<link rel="stylesheet" href="../../theme/stylesheets/prettify.css">
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="custom" data-md-color-accent="custom">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#schema" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Django REST framework" class="md-header__button md-logo" aria-label="Django REST framework" data-md-component="logo">
<img src="../../theme/img/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Django REST framework
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Schemas
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="custom" data-md-color-accent="custom" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m14.3 16-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9zM20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12zm-9.15 3.96h2.3L12 9z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="custom" data-md-color-accent="custom" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="custom" data-md-color-accent="custom" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/encode/django-rest-framework" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../tutorial/quickstart/" class="md-tabs__link">
Tutorial
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../requests/" class="md-tabs__link">
API Guide
</a>
</li>
<li class="md-tabs__item">
<a href="../../topics/documenting-your-api/" class="md-tabs__link">
Topics
</a>
</li>
<li class="md-tabs__item">
<a href="../../community/tutorials-and-resources/" class="md-tabs__link">
Community
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Django REST framework" class="md-nav__button md-logo" aria-label="Django REST framework" data-md-component="logo">
<img src="../../theme/img/logo.png" alt="logo">
</a>
Django REST framework
</label>
<div class="md-nav__source">
<a href="https://github.com/encode/django-rest-framework" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Tutorial
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Tutorial
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../tutorial/quickstart/" class="md-nav__link">
<span class="md-ellipsis">
Quickstart
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/1-serialization/" class="md-nav__link">
<span class="md-ellipsis">
1 - Serialization
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/2-requests-and-responses/" class="md-nav__link">
<span class="md-ellipsis">
2 - Requests and responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/3-class-based-views/" class="md-nav__link">
<span class="md-ellipsis">
3 - Class based views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/4-authentication-and-permissions/" class="md-nav__link">
<span class="md-ellipsis">
4 - Authentication and permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/5-relationships-and-hyperlinked-apis/" class="md-nav__link">
<span class="md-ellipsis">
5 - Relationships and hyperlinked APIs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/6-viewsets-and-routers/" class="md-nav__link">
<span class="md-ellipsis">
6 - Viewsets and routers
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-ellipsis">
API Guide
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
API Guide
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../requests/" class="md-nav__link">
<span class="md-ellipsis">
Requests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../responses/" class="md-nav__link">
<span class="md-ellipsis">
Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../generic-views/" class="md-nav__link">
<span class="md-ellipsis">
Generic views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../viewsets/" class="md-nav__link">
<span class="md-ellipsis">
Viewsets
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../routers/" class="md-nav__link">
<span class="md-ellipsis">
Routers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../parsers/" class="md-nav__link">
<span class="md-ellipsis">
Parsers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../renderers/" class="md-nav__link">
<span class="md-ellipsis">
Renderers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../serializers/" class="md-nav__link">
<span class="md-ellipsis">
Serializers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../fields/" class="md-nav__link">
<span class="md-ellipsis">
Serializer fields
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../relations/" class="md-nav__link">
<span class="md-ellipsis">
Serializer relations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../validators/" class="md-nav__link">
<span class="md-ellipsis">
Validators
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../authentication/" class="md-nav__link">
<span class="md-ellipsis">
Authentication
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../permissions/" class="md-nav__link">
<span class="md-ellipsis">
Permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../caching/" class="md-nav__link">
<span class="md-ellipsis">
Caching
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../throttling/" class="md-nav__link">
<span class="md-ellipsis">
Throttling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../filtering/" class="md-nav__link">
<span class="md-ellipsis">
Filtering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pagination/" class="md-nav__link">
<span class="md-ellipsis">
Pagination
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../versioning/" class="md-nav__link">
<span class="md-ellipsis">
Versioning
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../content-negotiation/" class="md-nav__link">
<span class="md-ellipsis">
Content negotiation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../metadata/" class="md-nav__link">
<span class="md-ellipsis">
Metadata
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Schemas
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Schemas
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#generating-an-openapi-schema" class="md-nav__link">
<span class="md-ellipsis">
Generating an OpenAPI Schema
</span>
</a>
<nav class="md-nav" aria-label="Generating an OpenAPI Schema">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#install-dependencies" class="md-nav__link">
<span class="md-ellipsis">
Install dependencies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#generating-a-static-schema-with-the-generateschema-management-command" class="md-nav__link">
<span class="md-ellipsis">
Generating a static schema with the generateschema management command
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#generating-a-dynamic-schema-with-schemaview" class="md-nav__link">
<span class="md-ellipsis">
Generating a dynamic schema with SchemaView
</span>
</a>
<nav class="md-nav" aria-label="Generating a dynamic schema with SchemaView">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get_schema_view" class="md-nav__link">
<span class="md-ellipsis">
get_schema_view()
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#schemagenerator" class="md-nav__link">
<span class="md-ellipsis">
SchemaGenerator
</span>
</a>
<nav class="md-nav" aria-label="SchemaGenerator">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get_schemaself-requestnone-publicfalse" class="md-nav__link">
<span class="md-ellipsis">
get_schema(self, request=None, public=False)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#autoschema" class="md-nav__link">
<span class="md-ellipsis">
AutoSchema
</span>
</a>
<nav class="md-nav" aria-label="AutoSchema">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#autoschema-methods" class="md-nav__link">
<span class="md-ellipsis">
AutoSchema methods
</span>
</a>
<nav class="md-nav" aria-label="AutoSchema methods">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get_components" class="md-nav__link">
<span class="md-ellipsis">
get_components()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_component_name" class="md-nav__link">
<span class="md-ellipsis">
get_component_name()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_reference" class="md-nav__link">
<span class="md-ellipsis">
get_reference()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#map_serializer" class="md-nav__link">
<span class="md-ellipsis">
map_serializer()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#map_field" class="md-nav__link">
<span class="md-ellipsis">
map_field()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_tags" class="md-nav__link">
<span class="md-ellipsis">
get_tags()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_operation" class="md-nav__link">
<span class="md-ellipsis">
get_operation()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_operation_id" class="md-nav__link">
<span class="md-ellipsis">
get_operation_id()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_operation_id_base" class="md-nav__link">
<span class="md-ellipsis">
get_operation_id_base()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_serializer" class="md-nav__link">
<span class="md-ellipsis">
get_serializer()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_request_serializer" class="md-nav__link">
<span class="md-ellipsis">
get_request_serializer()
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#get_response_serializer" class="md-nav__link">
<span class="md-ellipsis">
get_response_serializer()
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#autoschema__init__-kwargs" class="md-nav__link">
<span class="md-ellipsis">
AutoSchema.__init__() kwargs
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../format-suffixes/" class="md-nav__link">
<span class="md-ellipsis">
Format suffixes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../reverse/" class="md-nav__link">
<span class="md-ellipsis">
Returning URLs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../exceptions/" class="md-nav__link">
<span class="md-ellipsis">
Exceptions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../status-codes/" class="md-nav__link">
<span class="md-ellipsis">
Status codes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../testing/" class="md-nav__link">
<span class="md-ellipsis">
Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../settings/" class="md-nav__link">
<span class="md-ellipsis">
Settings
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Topics
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Topics
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../topics/documenting-your-api/" class="md-nav__link">
<span class="md-ellipsis">
Documenting your API
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../topics/internationalization/" class="md-nav__link">
<span class="md-ellipsis">
Internationalization
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../topics/ajax-csrf-cors/" class="md-nav__link">
<span class="md-ellipsis">
AJAX, CSRF & CORS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../topics/html-and-forms/" class="md-nav__link">
<span class="md-ellipsis">
HTML & Forms
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../topics/browser-enhancements/" class="md-nav__link">
<span class="md-ellipsis">
Browser Enhancements
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../topics/browsable-api/" class="md-nav__link">
<span class="md-ellipsis">
The Browsable API
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../topics/rest-hypermedia-hateoas/" class="md-nav__link">
<span class="md-ellipsis">
REST, Hypermedia & HATEOAS
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Community
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Community
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../community/tutorials-and-resources/" class="md-nav__link">
<span class="md-ellipsis">
Tutorials and Resources
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/third-party-packages/" class="md-nav__link">
<span class="md-ellipsis">
Third Party Packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/contributing/" class="md-nav__link">
<span class="md-ellipsis">
Contributing to REST framework
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/project-management/" class="md-nav__link">
<span class="md-ellipsis">
Project management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/release-notes/" class="md-nav__link">
<span class="md-ellipsis">
Release Notes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.16-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.16 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.15-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.15 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.14-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.14 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.13-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.13 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.12-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.12 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.11-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.11 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.10-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.10 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.9-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.9 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.8-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.8 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.7-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.7 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.6-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.6 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.5-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.5 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.4-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.4 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.3-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.3 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.2-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.2 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.1-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.1 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/3.0-announcement/" class="md-nav__link">
<span class="md-ellipsis">
3.0 Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/kickstarter-announcement/" class="md-nav__link">
<span class="md-ellipsis">
Kickstarter Announcement
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/mozilla-grant/" class="md-nav__link">
<span class="md-ellipsis">
Mozilla Grant
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../community/jobs/" class="md-nav__link">
<span class="md-ellipsis">
Jobs
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation" >
<ol class="md-path__list">
<li class="md-path__item">
<a href="../.." class="md-path__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-path__item">
<a href="../requests/" class="md-path__link">
<span class="md-ellipsis">
API Guide
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<h1 id="schema">Schema<a class="headerlink" href="#schema" title="Permanent link">&para;</a></h1>
<blockquote>
<p>A machine-readable [schema] describes what resources are available via the API, what their URLs are, how they are represented and what operations they support.</p>
<p>&mdash; Heroku, <a href="https://www.heroku.com/blog/json_schema_for_heroku_platform_api/">JSON Schema for the Heroku Platform API</a></p>
</blockquote>
<hr />
<p><strong>Deprecation notice:</strong></p>
<p>REST framework's built-in support for generating OpenAPI schemas is
<strong>deprecated</strong> in favor of 3rd party packages that can provide this
functionality instead. The built-in support will be moved into a separate
package and then subsequently retired over the next releases.</p>
<p>As a full-fledged replacement, we recommend the <a href="https://drf-spectacular.readthedocs.io/en/latest/readme.html">drf-spectacular</a> package.
It has extensive support for generating OpenAPI 3 schemas from
REST framework APIs, with both automatic and customizable options available.
For further information please refer to
<a href="../../topics/documenting-your-api/#drf-spectacular">Documenting your API</a>.</p>
<hr />
<p>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.</p>
<p>Django REST Framework provides support for automatic generation of
<a href="https://github.com/OAI/OpenAPI-Specification">OpenAPI</a> schemas.</p>
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
<p>Schema generation has several moving parts. It's worth having an overview:</p>
<ul>
<li><code>SchemaGenerator</code> is a top-level class that is responsible for walking your
configured URL patterns, finding <code>APIView</code> subclasses, enquiring for their
schema representation, and compiling the final schema object.</li>
<li><code>AutoSchema</code> encapsulates all the details necessary for per-view schema
introspection. Is attached to each view via the <code>schema</code> attribute. You
subclass <code>AutoSchema</code> in order to customize your schema.</li>
<li>The <code>generateschema</code> management command allows you to generate a static schema
offline.</li>
<li>Alternatively, you can route <code>SchemaView</code> to dynamically generate and serve
your schema.</li>
<li><code>settings.DEFAULT_SCHEMA_CLASS</code> allows you to specify an <code>AutoSchema</code>
subclass to serve as your project's default.</li>
</ul>
<p>The following sections explain more.</p>
<h2 id="generating-an-openapi-schema">Generating an OpenAPI Schema<a class="headerlink" href="#generating-an-openapi-schema" title="Permanent link">&para;</a></h2>
<h3 id="install-dependencies">Install dependencies<a class="headerlink" href="#install-dependencies" title="Permanent link">&para;</a></h3>
<div class="language-text highlight"><pre><span></span><code>pip install pyyaml uritemplate inflection
</code></pre></div>
<ul>
<li><code>pyyaml</code> is used to generate schema into YAML-based OpenAPI format.</li>
<li><code>uritemplate</code> is used internally to get parameters in path.</li>
<li><code>inflection</code> is used to pluralize operations more appropriately in the list endpoints.</li>
</ul>
<h3 id="generating-a-static-schema-with-the-generateschema-management-command">Generating a static schema with the <code>generateschema</code> management command<a class="headerlink" href="#generating-a-static-schema-with-the-generateschema-management-command" title="Permanent link">&para;</a></h3>
<p>If your schema is static, you can use the <code>generateschema</code> management command:</p>
<div class="language-bash highlight"><pre><span></span><code>./manage.py<span class="w"> </span>generateschema<span class="w"> </span>--file<span class="w"> </span>openapi-schema.yml
</code></pre></div>
<p>Once you've generated a schema in this way you can annotate it with any
additional information that cannot be automatically inferred by the schema
generator.</p>
<p>You might want to check your API schema into version control and update it
with each new release, or serve the API schema from your site's static media.</p>
<h3 id="generating-a-dynamic-schema-with-schemaview">Generating a dynamic schema with <code>SchemaView</code><a class="headerlink" href="#generating-a-dynamic-schema-with-schemaview" title="Permanent link">&para;</a></h3>
<p>If you require a dynamic schema, because foreign key choices depend on database
values, for example, you can route a <code>SchemaView</code> that will generate and serve
your schema on demand.</p>
<p>To route a <code>SchemaView</code>, use the <code>get_schema_view()</code> helper.</p>
<p>In <code>urls.py</code>:</p>
<div class="language-python highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">rest_framework.schemas</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_schema_view</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># ...</span>
<span class="c1"># Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.</span>
<span class="c1"># * `title` and `description` parameters are passed to `SchemaGenerator`.</span>
<span class="c1"># * Provide view name for use with `reverse()`.</span>
<span class="n">path</span><span class="p">(</span>
<span class="s2">&quot;openapi&quot;</span><span class="p">,</span>
<span class="n">get_schema_view</span><span class="p">(</span>
<span class="n">title</span><span class="o">=</span><span class="s2">&quot;Your Project&quot;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;API for all things …&quot;</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="s2">&quot;1.0.0&quot;</span>
<span class="p">),</span>
<span class="n">name</span><span class="o">=</span><span class="s2">&quot;openapi-schema&quot;</span><span class="p">,</span>
<span class="p">),</span>
<span class="c1"># ...</span>
<span class="p">]</span>
</code></pre></div>
<h4 id="get_schema_view"><code>get_schema_view()</code><a class="headerlink" href="#get_schema_view" title="Permanent link">&para;</a></h4>
<p>The <code>get_schema_view()</code> helper takes the following keyword arguments:</p>
<ul>
<li><code>title</code>: May be used to provide a descriptive title for the schema definition.</li>
<li><code>description</code>: Longer descriptive text.</li>
<li><code>version</code>: The version of the API.</li>
<li>
<p><code>url</code>: May be used to pass a canonical base URL for the schema.</p>
<div class="language-text highlight"><pre><span></span><code>schema_view = get_schema_view(
title=&#39;Server Monitoring API&#39;,
url=&#39;https://www.example.org/api/&#39;
)
</code></pre></div>
</li>
<li>
<p><code>urlconf</code>: A string representing the import path to the URL conf that you want
to generate an API schema for. This defaults to the value of Django's
<code>ROOT_URLCONF</code> setting.</p>
<div class="language-text highlight"><pre><span></span><code>schema_view = get_schema_view(
title=&#39;Server Monitoring API&#39;,
url=&#39;https://www.example.org/api/&#39;,
urlconf=&#39;myproject.urls&#39;
)
</code></pre></div>
</li>
<li>
<p><code>patterns</code>: List of url patterns to limit the schema introspection to. If you
only want the <code>myproject.api</code> urls to be exposed in the schema:</p>
<div class="language-text highlight"><pre><span></span><code>schema_url_patterns = [
path(&#39;api/&#39;, include(&#39;myproject.api.urls&#39;)),
]
schema_view = get_schema_view(
title=&#39;Server Monitoring API&#39;,
url=&#39;https://www.example.org/api/&#39;,
patterns=schema_url_patterns,
)
</code></pre></div>
<ul>
<li><code>public</code>: May be used to specify if schema should bypass views permissions. Default to False</li>
</ul>
</li>
<li>
<p><code>generator_class</code>: May be used to specify a <code>SchemaGenerator</code> subclass to be
passed to the <code>SchemaView</code>.</p>
</li>
<li><code>authentication_classes</code>: May be used to specify the list of authentication
classes that will apply to the schema endpoint. Defaults to
<code>settings.DEFAULT_AUTHENTICATION_CLASSES</code></li>
<li><code>permission_classes</code>: May be used to specify the list of permission classes
that will apply to the schema endpoint. Defaults to
<code>settings.DEFAULT_PERMISSION_CLASSES</code>.</li>
<li><code>renderer_classes</code>: May be used to pass the set of renderer classes that can
be used to render the API root endpoint.</li>
</ul>
<h2 id="schemagenerator">SchemaGenerator<a class="headerlink" href="#schemagenerator" title="Permanent link">&para;</a></h2>
<p><strong>Schema-level customization</strong></p>
<div class="language-python highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">rest_framework.schemas.openapi</span><span class="w"> </span><span class="kn">import</span> <span class="n">SchemaGenerator</span>
</code></pre></div>
<p><code>SchemaGenerator</code> is a class that walks a list of routed URL patterns, requests
the schema for each view and collates the resulting OpenAPI schema.</p>
<p>Typically you won't need to instantiate <code>SchemaGenerator</code> yourself, but you can
do so like so:</p>
<div class="language-text highlight"><pre><span></span><code>generator = SchemaGenerator(title=&#39;Stock Prices API&#39;)
</code></pre></div>
<p>Arguments:</p>
<ul>
<li><code>title</code> <strong>required</strong>: The name of the API.</li>
<li><code>description</code>: Longer descriptive text.</li>
<li><code>version</code>: The version of the API. Defaults to <code>0.1.0</code>.</li>
<li><code>url</code>: The root URL of the API schema. This option is not required unless the schema is included under path prefix.</li>
<li><code>patterns</code>: A list of URLs to inspect when generating the schema. Defaults to the project's URL conf.</li>
<li><code>urlconf</code>: A URL conf module name to use when generating the schema. Defaults to <code>settings.ROOT_URLCONF</code>.</li>
</ul>
<p>In order to customize the top-level schema, subclass
<code>rest_framework.schemas.openapi.SchemaGenerator</code> and provide your subclass
as an argument to the <code>generateschema</code> command or <code>get_schema_view()</code> helper
function.</p>
<h3 id="get_schemaself-requestnone-publicfalse">get_schema(self, request=None, public=False)<a class="headerlink" href="#get_schemaself-requestnone-publicfalse" title="Permanent link">&para;</a></h3>
<p>Returns a dictionary that represents the OpenAPI schema:</p>
<div class="language-text highlight"><pre><span></span><code>generator = SchemaGenerator(title=&#39;Stock Prices API&#39;)
schema = generator.get_schema()
</code></pre></div>
<p>The <code>request</code> argument is optional, and may be used if you want to apply
per-user permissions to the resulting schema generation.</p>
<p>This is a good point to override if you want to customize the generated
dictionary For example you might wish to add terms of service to the <a href="https://swagger.io/specification/#infoObject">top-level
<code>info</code> object</a>:</p>
<div class="language-text highlight"><pre><span></span><code>class TOSSchemaGenerator(SchemaGenerator):
def get_schema(self, *args, **kwargs):
schema = super().get_schema(*args, **kwargs)
schema[&quot;info&quot;][&quot;termsOfService&quot;] = &quot;https://example.com/tos.html&quot;
return schema
</code></pre></div>
<h2 id="autoschema">AutoSchema<a class="headerlink" href="#autoschema" title="Permanent link">&para;</a></h2>
<p><strong>Per-View Customization</strong></p>
<div class="language-python highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">rest_framework.schemas.openapi</span><span class="w"> </span><span class="kn">import</span> <span class="n">AutoSchema</span>
</code></pre></div>
<p>By default, view introspection is performed by an <code>AutoSchema</code> instance
accessible via the <code>schema</code> attribute on <code>APIView</code>.</p>
<div class="language-text highlight"><pre><span></span><code>auto_schema = some_view.schema
</code></pre></div>
<p><code>AutoSchema</code> provides the OpenAPI elements needed for each view, request method
and path:</p>
<ul>
<li>A list of <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#componentsObject">OpenAPI components</a>. In DRF terms these are
mappings of serializers that describe request and response bodies.</li>
<li>The appropriate <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#operationObject">OpenAPI operation object</a> that describes
the endpoint, including path and query parameters for pagination, filtering,
and so on.</li>
</ul>
<div class="language-python highlight"><pre><span></span><code><span class="n">components</span> <span class="o">=</span> <span class="n">auto_schema</span><span class="o">.</span><span class="n">get_components</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">operation</span> <span class="o">=</span> <span class="n">auto_schema</span><span class="o">.</span><span class="n">get_operation</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
</code></pre></div>
<p>In compiling the schema, <code>SchemaGenerator</code> calls <code>get_components()</code> and
<code>get_operation()</code> for each view, allowed method, and path.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The automatic introspection of components, and many operation
parameters relies on the relevant attributes and methods of
<code>GenericAPIView</code>: <code>get_serializer()</code>, <code>pagination_class</code>, <code>filter_backends</code>,
etc. For basic <code>APIView</code> subclasses, default introspection is essentially limited to
the URL kwarg path parameters for this reason.</p>
</div>
<p><code>AutoSchema</code> encapsulates the view introspection needed for schema generation.
Because of this all the schema generation logic is kept in a single place,
rather than being spread around the already extensive view, serializer and
field APIs.</p>
<p>Keeping with this pattern, try not to let schema logic leak into your own
views, serializers, or fields when customizing the schema generation. You might
be tempted to do something like this:</p>
<div class="language-python highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">CustomSchema</span><span class="p">(</span><span class="n">AutoSchema</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> AutoSchema subclass using schema_extra_info on the view.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="o">...</span>
<span class="k">class</span><span class="w"> </span><span class="nc">CustomView</span><span class="p">(</span><span class="n">APIView</span><span class="p">):</span>
<span class="n">schema</span> <span class="o">=</span> <span class="n">CustomSchema</span><span class="p">()</span>
<span class="n">schema_extra_info</span> <span class="o">=</span> <span class="o">...</span> <span class="c1"># some extra info</span>
</code></pre></div>
<p>Here, the <code>AutoSchema</code> subclass goes looking for <code>schema_extra_info</code> on the
view. This is <em>OK</em> (it doesn't actually hurt) but it means you'll end up with
your schema logic spread out in a number of different places.</p>
<p>Instead try to subclass <code>AutoSchema</code> such that the <code>extra_info</code> doesn't leak
out into the view:</p>
<div class="language-python highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">BaseSchema</span><span class="p">(</span><span class="n">AutoSchema</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> AutoSchema subclass that knows how to use extra_info.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="o">...</span>
<span class="k">class</span><span class="w"> </span><span class="nc">CustomSchema</span><span class="p">(</span><span class="n">BaseSchema</span><span class="p">):</span>
<span class="n">extra_info</span> <span class="o">=</span> <span class="o">...</span> <span class="c1"># some extra info</span>
<span class="k">class</span><span class="w"> </span><span class="nc">CustomView</span><span class="p">(</span><span class="n">APIView</span><span class="p">):</span>
<span class="n">schema</span> <span class="o">=</span> <span class="n">CustomSchema</span><span class="p">()</span>
</code></pre></div>
<p>This style is slightly more verbose but maintains the encapsulation of the
schema related code. It's more <em>cohesive</em> in the <em>parlance</em>. It'll keep the
rest of your API code more tidy.</p>
<p>If an option applies to many view classes, rather than creating a specific
subclass per-view, you may find it more convenient to allow specifying the
option as an <code>__init__()</code> kwarg to your base <code>AutoSchema</code> subclass:</p>
<div class="language-python highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">CustomSchema</span><span class="p">(</span><span class="n">BaseSchema</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="c1"># store extra_info for later</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra_info</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;extra_info&quot;</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">CustomView</span><span class="p">(</span><span class="n">APIView</span><span class="p">):</span>
<span class="n">schema</span> <span class="o">=</span> <span class="n">CustomSchema</span><span class="p">(</span><span class="n">extra_info</span><span class="o">=...</span><span class="p">)</span> <span class="c1"># some extra info</span>
</code></pre></div>
<p>This saves you having to create a custom subclass per-view for a commonly used option.</p>
<p>Not all <code>AutoSchema</code> methods expose related <code>__init__()</code> kwargs, but those for
the more commonly needed options do.</p>
<h3 id="autoschema-methods"><code>AutoSchema</code> methods<a class="headerlink" href="#autoschema-methods" title="Permanent link">&para;</a></h3>
<h4 id="get_components"><code>get_components()</code><a class="headerlink" href="#get_components" title="Permanent link">&para;</a></h4>
<p>Generates the OpenAPI components that describe request and response bodies,
deriving their properties from the serializer.</p>
<p>Returns a dictionary mapping the component name to the generated
representation. By default this has just a single pair but you may override
<code>get_components()</code> to return multiple pairs if your view uses multiple
serializers.</p>
<h4 id="get_component_name"><code>get_component_name()</code><a class="headerlink" href="#get_component_name" title="Permanent link">&para;</a></h4>
<p>Computes the component's name from the serializer.</p>
<p>You may see warnings if your API has duplicate component names. If so you can override <code>get_component_name()</code> or pass the <code>component_name</code> <code>__init__()</code> kwarg (see below) to provide different names.</p>
<h4 id="get_reference"><code>get_reference()</code><a class="headerlink" href="#get_reference" title="Permanent link">&para;</a></h4>
<p>Returns a reference to the serializer component. This may be useful if you override <code>get_schema()</code>.</p>
<h4 id="map_serializer"><code>map_serializer()</code><a class="headerlink" href="#map_serializer" title="Permanent link">&para;</a></h4>
<p>Maps serializers to their OpenAPI representations.</p>
<p>Most serializers should conform to the standard OpenAPI <code>object</code> type, but you may
wish to override <code>map_serializer()</code> in order to customize this or other
serializer-level fields.</p>
<h4 id="map_field"><code>map_field()</code><a class="headerlink" href="#map_field" title="Permanent link">&para;</a></h4>
<p>Maps individual serializer fields to their schema representation. The base implementation
will handle the default fields that Django REST Framework provides.</p>
<p>For <code>SerializerMethodField</code> instances, for which the schema is unknown, or custom field subclasses you should override <code>map_field()</code> to generate the correct schema:</p>
<div class="language-python highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">CustomSchema</span><span class="p">(</span><span class="n">AutoSchema</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Extension of ``AutoSchema`` to add support for custom field schemas.&quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">map_field</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">):</span>
<span class="c1"># Handle SerializerMethodFields or custom fields here...</span>
<span class="c1"># ...</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">map_field</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
</code></pre></div>
<p>Authors of third-party packages should aim to provide an <code>AutoSchema</code> subclass,
and a mixin, overriding <code>map_field()</code> so that users can easily generate schemas
for their custom fields.</p>
<h4 id="get_tags"><code>get_tags()</code><a class="headerlink" href="#get_tags" title="Permanent link">&para;</a></h4>
<p>OpenAPI groups operations by tags. By default tags taken from the first path
segment of the routed URL. For example, a URL like <code>/users/{id}/</code> will generate
the tag <code>users</code>.</p>
<p>You can pass an <code>__init__()</code> kwarg to manually specify tags (see below), or
override <code>get_tags()</code> to provide custom logic.</p>
<h4 id="get_operation"><code>get_operation()</code><a class="headerlink" href="#get_operation" title="Permanent link">&para;</a></h4>
<p>Returns the <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#operationObject">OpenAPI operation object</a> that describes the
endpoint, including path and query parameters for pagination, filtering, and so
on.</p>
<p>Together with <code>get_components()</code>, this is the main entry point to the view
introspection.</p>
<h4 id="get_operation_id"><code>get_operation_id()</code><a class="headerlink" href="#get_operation_id" title="Permanent link">&para;</a></h4>
<p>There must be a unique <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#fixed-fields-17">operationid</a> for each operation.
By default the <code>operationId</code> is deduced from the model name, serializer name or
view name. The operationId looks like "listItems", "retrieveItem",
"updateItem", etc. The <code>operationId</code> is camelCase by convention.</p>
<h4 id="get_operation_id_base"><code>get_operation_id_base()</code><a class="headerlink" href="#get_operation_id_base" title="Permanent link">&para;</a></h4>
<p>If you have several views with the same model name, you may see duplicate
operationIds.</p>
<p>In order to work around this, you can override <code>get_operation_id_base()</code> to
provide a different base for name part of the ID.</p>
<h4 id="get_serializer"><code>get_serializer()</code><a class="headerlink" href="#get_serializer" title="Permanent link">&para;</a></h4>
<p>If the view has implemented <code>get_serializer()</code>, returns the result.</p>
<h4 id="get_request_serializer"><code>get_request_serializer()</code><a class="headerlink" href="#get_request_serializer" title="Permanent link">&para;</a></h4>
<p>By default returns <code>get_serializer()</code> but can be overridden to
differentiate between request and response objects.</p>
<h4 id="get_response_serializer"><code>get_response_serializer()</code><a class="headerlink" href="#get_response_serializer" title="Permanent link">&para;</a></h4>
<p>By default returns <code>get_serializer()</code> but can be overridden to
differentiate between request and response objects.</p>
<h3 id="autoschema__init__-kwargs"><code>AutoSchema.__init__()</code> kwargs<a class="headerlink" href="#autoschema__init__-kwargs" title="Permanent link">&para;</a></h3>
<p><code>AutoSchema</code> provides a number of <code>__init__()</code> kwargs that can be used for
common customizations, if the default generated values are not appropriate.</p>
<p>The available kwargs are:</p>
<ul>
<li><code>tags</code>: Specify a list of tags.</li>
<li><code>component_name</code>: Specify the component name.</li>
<li><code>operation_id_base</code>: Specify the resource-name part of operation IDs.</li>
</ul>
<p>You pass the kwargs when declaring the <code>AutoSchema</code> instance on your view:</p>
<div class="language-text highlight"><pre><span></span><code>class PetDetailView(generics.RetrieveUpdateDestroyAPIView):
schema = AutoSchema(
tags=[&#39;Pets&#39;],
component_name=&#39;Pet&#39;,
operation_id_base=&#39;Pet&#39;,
)
...
</code></pre></div>
<p>Assuming a <code>Pet</code> model and <code>PetSerializer</code> serializer, the kwargs in this
example are probably not needed. Often, though, you'll need to pass the kwargs
if you have multiple view targeting the same model, or have multiple views with
identically named serializers.</p>
<p>If your views have related customizations that are needed frequently, you can
create a base <code>AutoSchema</code> subclass for your project that takes additional
<code>__init__()</code> kwargs to save subclassing <code>AutoSchema</code> for each view.</p>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<div class="md-progress" data-md-component="progress" role="progressbar"></div>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["content.tabs.link", "content.code.annotate", "content.code.copy", "navigation.tabs", "navigation.tabs.sticky", "navigation.instant", "navigation.instant.prefetch", "navigation.instant.progress", "navigation.path", "navigation.sections", "navigation.top", "navigation.tracking", "search.suggest", "toc.follow", "toc.integrate"], "search": "../../assets/javascripts/workers/search.7a47a382.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.e71a0d61.min.js"></script>
<script src="../../theme/js/prettify-1.0.js"></script>
<script>
document$.subscribe(function() {
document.querySelectorAll('pre code').forEach(code => {
code.parentElement.classList.add('prettyprint', 'well');
});
prettyPrint();
});
</script>
</body>
</html>