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

851 lines
35 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Schemas - Django REST framework</title>
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="canonical" href="https://www.django-rest-framework.org/api-guide/schemas/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Django, API, REST, Schemas">
<meta name="author" content="Tom Christie">
<!-- Le styles -->
<link href="../../css/prettify.css" rel="stylesheet">
<link href="../../css/bootstrap.css" rel="stylesheet">
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
<link href="../../css/default.css" rel="stylesheet">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-18852272-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
<style>
#sidebarInclude img {
margin-bottom: 10px;
}
#sidebarInclude a.promo {
color: black;
}
@media (max-width: 767px) {
div.promo {
display: none;
}
}
</style>
</head>
<body onload="prettyPrint()" class="-page">
<div class="wrapper">
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="repo-link btn btn-primary btn-small" href="https://github.com/encode/django-rest-framework/tree/master">GitHub</a>
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../format-suffixes/">
Next <i class="icon-arrow-right icon-white"></i>
</a>
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../metadata/">
<i class="icon-arrow-left icon-white"></i> Previous
</a>
<a id="search_modal_show" class="repo-link btn btn-inverse btn-small" href="#mkdocs_search_modal" data-toggle="modal" data-target="#mkdocs_search_modal"><i class="icon-search icon-white"></i> Search</a>
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="https://www.django-rest-framework.org/">Django REST framework</a>
<div class="nav-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav">
<li >
<a href="../..">Home</a>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
<ul class="dropdown-menu">
<li >
<a href="../../tutorial/quickstart/">Quickstart</a>
</li>
<li >
<a href="../../tutorial/1-serialization/">1 - Serialization</a>
</li>
<li >
<a href="../../tutorial/2-requests-and-responses/">2 - Requests and responses</a>
</li>
<li >
<a href="../../tutorial/3-class-based-views/">3 - Class based views</a>
</li>
<li >
<a href="../../tutorial/4-authentication-and-permissions/">4 - Authentication and permissions</a>
</li>
<li >
<a href="../../tutorial/5-relationships-and-hyperlinked-apis/">5 - Relationships and hyperlinked APIs</a>
</li>
<li >
<a href="../../tutorial/6-viewsets-and-routers/">6 - Viewsets and routers</a>
</li>
</ul>
</li>
<li class="dropdown active">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
<ul class="dropdown-menu">
<li >
<a href="../requests/">Requests</a>
</li>
<li >
<a href="../responses/">Responses</a>
</li>
<li >
<a href="../views/">Views</a>
</li>
<li >
<a href="../generic-views/">Generic views</a>
</li>
<li >
<a href="../viewsets/">Viewsets</a>
</li>
<li >
<a href="../routers/">Routers</a>
</li>
<li >
<a href="../parsers/">Parsers</a>
</li>
<li >
<a href="../renderers/">Renderers</a>
</li>
<li >
<a href="../serializers/">Serializers</a>
</li>
<li >
<a href="../fields/">Serializer fields</a>
</li>
<li >
<a href="../relations/">Serializer relations</a>
</li>
<li >
<a href="../validators/">Validators</a>
</li>
<li >
<a href="../authentication/">Authentication</a>
</li>
<li >
<a href="../permissions/">Permissions</a>
</li>
<li >
<a href="../caching/">Caching</a>
</li>
<li >
<a href="../throttling/">Throttling</a>
</li>
<li >
<a href="../filtering/">Filtering</a>
</li>
<li >
<a href="../pagination/">Pagination</a>
</li>
<li >
<a href="../versioning/">Versioning</a>
</li>
<li >
<a href="../content-negotiation/">Content negotiation</a>
</li>
<li >
<a href="../metadata/">Metadata</a>
</li>
<li class="active" >
<a href="./">Schemas</a>
</li>
<li >
<a href="../format-suffixes/">Format suffixes</a>
</li>
<li >
<a href="../reverse/">Returning URLs</a>
</li>
<li >
<a href="../exceptions/">Exceptions</a>
</li>
<li >
<a href="../status-codes/">Status codes</a>
</li>
<li >
<a href="../testing/">Testing</a>
</li>
<li >
<a href="../settings/">Settings</a>
</li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
<ul class="dropdown-menu">
<li >
<a href="../../topics/documenting-your-api/">Documenting your API</a>
</li>
<li >
<a href="../../topics/api-clients/">API Clients</a>
</li>
<li >
<a href="../../topics/internationalization/">Internationalization</a>
</li>
<li >
<a href="../../topics/ajax-csrf-cors/">AJAX, CSRF & CORS</a>
</li>
<li >
<a href="../../topics/html-and-forms/">HTML & Forms</a>
</li>
<li >
<a href="../../topics/browser-enhancements/">Browser Enhancements</a>
</li>
<li >
<a href="../../topics/browsable-api/">The Browsable API</a>
</li>
<li >
<a href="../../topics/rest-hypermedia-hateoas/">REST, Hypermedia & HATEOAS</a>
</li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Community <b class="caret"></b></a>
<ul class="dropdown-menu">
<li >
<a href="../../community/tutorials-and-resources/">Tutorials and Resources</a>
</li>
<li >
<a href="../../community/third-party-packages/">Third Party Packages</a>
</li>
<li >
<a href="../../community/contributing/">Contributing to REST framework</a>
</li>
<li >
<a href="../../community/project-management/">Project management</a>
</li>
<li >
<a href="../../community/release-notes/">Release Notes</a>
</li>
<li >
<a href="../../community/3.11-announcement/">3.11 Announcement</a>
</li>
<li >
<a href="../../community/3.10-announcement/">3.10 Announcement</a>
</li>
<li >
<a href="../../community/3.9-announcement/">3.9 Announcement</a>
</li>
<li >
<a href="../../community/3.8-announcement/">3.8 Announcement</a>
</li>
<li >
<a href="../../community/3.7-announcement/">3.7 Announcement</a>
</li>
<li >
<a href="../../community/3.6-announcement/">3.6 Announcement</a>
</li>
<li >
<a href="../../community/3.5-announcement/">3.5 Announcement</a>
</li>
<li >
<a href="../../community/3.4-announcement/">3.4 Announcement</a>
</li>
<li >
<a href="../../community/3.3-announcement/">3.3 Announcement</a>
</li>
<li >
<a href="../../community/3.2-announcement/">3.2 Announcement</a>
</li>
<li >
<a href="../../community/3.1-announcement/">3.1 Announcement</a>
</li>
<li >
<a href="../../community/3.0-announcement/">3.0 Announcement</a>
</li>
<li >
<a href="../../community/kickstarter-announcement/">Kickstarter Announcement</a>
</li>
<li >
<a href="../../community/mozilla-grant/">Mozilla Grant</a>
</li>
<li >
<a href="../../community/funding/">Funding</a>
</li>
<li >
<a href="../../community/jobs/">Jobs</a>
</li>
</ul>
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
</div>
</div>
<div class="body-content">
<div class="container-fluid">
<!-- Search Modal -->
<div id="mkdocs_search_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3 id="myModalLabel">Documentation search</h3>
</div>
<div class="modal-body">
<form role="form" autocomplete="off">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search..." id="mkdocs-search-query">
</div>
</form>
<div id="mkdocs-search-results"></div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
<div class="row-fluid">
<div class="span3">
<div id="table-of-contents">
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
<li class="main">
<a href="#schema">Schema</a>
</li>
<li>
<a href="#generating-an-openapi-schema">Generating an OpenAPI Schema</a>
</li>
<li>
<a href="#customizing-schema-generation">Customizing Schema Generation</a>
</li>
<div class="promo">
<hr/>
<div id="sidebarInclude">
</div>
</ul>
</div>
</div>
<div id="main-content" class="span9">
<a class="github" href="https://github.com/encode/django-rest-framework/tree/master/rest_framework/schemas">
<span class="label label-info">schemas</span>
</a>
<h1 id="schema"><a class="toclink" href="#schema">Schema</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, [JSON Schema for the Heroku Platform API][cite]</p>
</blockquote>
<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="generating-an-openapi-schema"><a class="toclink" href="#generating-an-openapi-schema">Generating an OpenAPI Schema</a></h2>
<h3 id="install-dependencies"><a class="toclink" href="#install-dependencies">Install dependencies</a></h3>
<pre><code>pip install pyyaml uritemplate
</code></pre>
<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>
</ul>
<h3 id="generating-a-static-schema-with-the-generateschema-management-command"><a class="toclink" href="#generating-a-static-schema-with-the-generateschema-management-command">Generating a static schema with the <code>generateschema</code> management command</a></h3>
<p>If your schema is static, you can use the <code>generateschema</code> management command:</p>
<pre><code class="bash">./manage.py generateschema --file openapi-schema.yml
</code></pre>
<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"><a class="toclink" href="#generating-a-dynamic-schema-with-schemaview">Generating a dynamic schema with <code>SchemaView</code></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>
<pre><code class="python">from rest_framework.schemas import get_schema_view
urlpatterns = [
# ...
# Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.
# * `title` and `description` parameters are passed to `SchemaGenerator`.
# * Provide view name for use with `reverse()`.
path('openapi', get_schema_view(
title=&quot;Your Project&quot;,
description=&quot;API for all things …&quot;,
version=&quot;1.0.0&quot;
), name='openapi-schema'),
# ...
]
</code></pre>
<h4 id="get_schema_view"><a class="toclink" href="#get_schema_view"><code>get_schema_view()</code></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>
<pre><code>schema_view = get_schema_view(
title='Server Monitoring API',
url='https://www.example.org/api/'
)
</code></pre>
</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>
<pre><code>schema_view = get_schema_view(
title='Server Monitoring API',
url='https://www.example.org/api/',
urlconf='myproject.urls'
)
</code></pre>
</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>
<pre><code>schema_url_patterns = [
url(r'^api/', include('myproject.api.urls')),
]
schema_view = get_schema_view(
title='Server Monitoring API',
url='https://www.example.org/api/',
patterns=schema_url_patterns,
)
</code></pre>
</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="customizing-schema-generation"><a class="toclink" href="#customizing-schema-generation">Customizing Schema Generation</a></h2>
<p>You may customize schema generation at the level of the schema as a whole, or
on a per-view basis.</p>
<h3 id="schema-level-customization"><a class="toclink" href="#schema-level-customization">Schema Level Customization</a></h3>
<p>In order to customize the top-level schema subclass
<code>rest_framework.schemas.openapi.SchemaGenerator</code> and provide it as an argument
to the <code>generateschema</code> command or <code>get_schema_view()</code> helper function.</p>
<h4 id="schemagenerator"><a class="toclink" href="#schemagenerator">SchemaGenerator</a></h4>
<p>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'll instantiate <code>SchemaGenerator</code> with a <code>title</code> argument, like so:</p>
<pre><code>generator = SchemaGenerator(title='Stock Prices API')
</code></pre>
<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>
<h5 id="get_schemaself-request"><a class="toclink" href="#get_schemaself-request">get_schema(self, request)</a></h5>
<p>Returns a dictionary that represents the OpenAPI schema:</p>
<pre><code>generator = SchemaGenerator(title='Stock Prices API')
schema = generator.get_schema()
</code></pre>
<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 to add custom
<a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#specification-extensions">specification extensions</a>.</p>
<h3 id="per-view-customization"><a class="toclink" href="#per-view-customization">Per-View Customization</a></h3>
<p>By default, view introspection is performed by an <code>AutoSchema</code> instance
accessible via the <code>schema</code> attribute on <code>APIView</code>. This provides the
appropriate <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject">Open API operation object</a> for the view,
request method and path:</p>
<pre><code>auto_schema = view.schema
operation = auto_schema.get_operation(...)
</code></pre>
<p>In compiling the schema, <code>SchemaGenerator</code> calls <code>view.schema.get_operation()</code>
for each view, allowed method, and path.</p>
<hr />
<p><strong>Note</strong>: For basic <code>APIView</code> subclasses, default introspection is essentially
limited to the URL kwarg path parameters. For <code>GenericAPIView</code>
subclasses, which includes all the provided class based views, <code>AutoSchema</code> will
attempt to introspect serializer, pagination and filter fields, as well as
provide richer path field descriptions. (The key hooks here are the relevant
<code>GenericAPIView</code> attributes and methods: <code>get_serializer</code>, <code>pagination_class</code>,
<code>filter_backends</code> and so on.)</p>
<hr />
<p>In order to customize the operation generation, you should provide an <code>AutoSchema</code> subclass, overriding <code>get_operation()</code> as you need:</p>
<pre><code> from rest_framework.views import APIView
from rest_framework.schemas.openapi import AutoSchema
class CustomSchema(AutoSchema):
def get_operation(...):
# Implement custom introspection here (or in other sub-methods)
class CustomView(APIView):
"""APIView subclass with custom schema introspection."""
schema = CustomSchema()
</code></pre>
<p>This provides complete control over view introspection.</p>
<p>You may disable schema generation for a view by setting <code>schema</code> to <code>None</code>:</p>
<pre><code>class CustomView(APIView):
...
schema = None # Will not appear in schema
</code></pre>
<p>This also applies to extra actions for <code>ViewSet</code>s:</p>
<pre><code>class CustomViewSet(viewsets.ModelViewSet):
@action(detail=True, schema=None)
def extra_action(self, request, pk=None):
...
</code></pre>
<p>If you wish to provide a base <code>AutoSchema</code> subclass to be used throughout your
project you may adjust <code>settings.DEFAULT_SCHEMA_CLASS</code> appropriately.</p>
<h3 id="grouping-operations-with-tags"><a class="toclink" href="#grouping-operations-with-tags">Grouping Operations With Tags</a></h3>
<p>Tags can be used to group logical operations. Each tag name in the list MUST be unique. </p>
<hr />
<h4 id="django-rest-framework-generates-tags-automatically-with-the-following-logic"><a class="toclink" href="#django-rest-framework-generates-tags-automatically-with-the-following-logic">Django REST Framework generates tags automatically with the following logic:</a></h4>
<p>Tag name will be first element from the path. Also, any <code>_</code> in path name will be replaced by a <code>-</code>.
Consider below examples.</p>
<p>Example 1: Consider a user management system. The following table will illustrate the tag generation logic.
Here first element from the paths is: <code>users</code>. Hence tag wil be <code>users</code></p>
<table>
<thead>
<tr>
<th>Http Method</th>
<th>Path</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
<tr>
<td>PUT, PATCH, GET(Retrieve), DELETE</td>
<td>/users/{id}/</td>
<td>['users']</td>
</tr>
<tr>
<td>POST, GET(List)</td>
<td>/users/</td>
<td>['users']</td>
</tr>
</tbody>
</table>
<p>Example 2: Consider a restaurant management system. The System has restaurants. Each restaurant has branches.
Consider REST APIs to deal with a branch of a particular restaurant.
Here first element from the paths is: <code>restaurants</code>. Hence tag wil be <code>restaurants</code>.</p>
<table>
<thead>
<tr>
<th>Http Method</th>
<th>Path</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
<tr>
<td>PUT, PATCH, GET(Retrieve), DELETE:</td>
<td>/restaurants/{restaurant_id}/branches/{branch_id}</td>
<td>['restaurants']</td>
</tr>
<tr>
<td>POST, GET(List):</td>
<td>/restaurants/{restaurant_id}/branches/</td>
<td>['restaurants']</td>
</tr>
</tbody>
</table>
<p>Example 3: Consider Order items for an e commerce company.</p>
<table>
<thead>
<tr>
<th>Http Method</th>
<th>Path</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
<tr>
<td>PUT, PATCH, GET(Retrieve), DELETE</td>
<td>/order_items/{id}/</td>
<td>['order-items']</td>
</tr>
<tr>
<td>POST, GET(List)</td>
<td>/order_items/</td>
<td>['order-items']</td>
</tr>
</tbody>
</table>
<hr />
<h4 id="overriding-auto-generated-tags"><a class="toclink" href="#overriding-auto-generated-tags">Overriding auto generated tags:</a></h4>
<p>You can override auto-generated tags by passing <code>tags</code> argument to the constructor of <code>AutoSchema</code>. <code>tags</code> argument must be a list or tuple of string.</p>
<pre><code class="python">from rest_framework.schemas.openapi import AutoSchema
from rest_framework.views import APIView
class MyView(APIView):
schema = AutoSchema(tags=['tag1', 'tag2'])
...
</code></pre>
<p>If you need more customization, you can override the <code>get_tags</code> method of <code>AutoSchema</code> class. Consider the following example:</p>
<pre><code class="python">from rest_framework.schemas.openapi import AutoSchema
from rest_framework.views import APIView
class MySchema(AutoSchema):
...
def get_tags(self, path, method):
if method == 'POST':
tags = ['tag1', 'tag2']
elif method == 'GET':
tags = ['tag2', 'tag3']
elif path == '/example/path/':
tags = ['tag3', 'tag4']
else:
tags = ['tag5', 'tag6', 'tag7']
return tags
class MyView(APIView):
schema = MySchema()
...
</code></pre>
<h3 id="operationid"><a class="toclink" href="#operationid">OperationId</a></h3>
<p>The schema generator generates an <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields-17">operationid</a> for each operation. This <code>operationId</code> is deduced from the model name, serializer name or view name. The operationId may looks like "listItems", "retrieveItem", "updateItem", etc..
The <code>operationId</code> is camelCase by convention.</p>
<p>If you have several views with the same model, the generator may generate duplicate operationId.
In order to work around this, you can override the second part of the operationId: operation name.</p>
<pre><code class="python">from rest_framework.schemas.openapi import AutoSchema
class ExampleView(APIView):
&quot;&quot;&quot;APIView subclass with custom schema introspection.&quot;&quot;&quot;
schema = AutoSchema(operation_id_base=&quot;Custom&quot;)
</code></pre>
<p>The previous example will generate the following operationId: "listCustoms", "retrieveCustom", "updateCustom", "partialUpdateCustom", "destroyCustom".
You need to provide the singular form of he operation name. For the list operation, a "s" will be appended at the end of the operation.</p>
<p>If you need more configuration over the <code>operationId</code> field, you can override the <code>get_operation_id_base</code> and <code>get_operation_id</code> methods from the <code>AutoSchema</code> class:</p>
<pre><code class="python">class CustomSchema(AutoSchema):
def get_operation_id_base(self, path, method, action):
pass
def get_operation_id(self, path, method):
pass
class MyView(APIView):
schema = AutoSchema(component_name=&quot;Ulysses&quot;)
</code></pre>
<h3 id="components"><a class="toclink" href="#components">Components</a></h3>
<p>Since DRF 3.12, Schema uses the <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#componentsObject">OpenAPI Components</a>. This method defines components in the schema and <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#referenceObject">references them</a> inside request and response objects. By default, the component's name is deduced from the Serializer's name.</p>
<p>Using OpenAPI's components provides the following advantages:</p>
<ul>
<li>The schema is more readable and lightweight.</li>
<li>If you use the schema to generate an SDK (using <a href="https://github.com/OpenAPITools/openapi-generator">openapi-generator</a> or <a href="https://github.com/swagger-api/swagger-codegen">swagger-codegen</a>). The generator can name your SDK's models.</li>
</ul>
<h3 id="handling-components-schema-errors"><a class="toclink" href="#handling-components-schema-errors">Handling component's schema errors</a></h3>
<p>You may get the following error while generating the schema:</p>
<pre><code>&quot;Serializer&quot; is an invalid class name for schema generation.
Serializer's class name should be unique and explicit. e.g. &quot;ItemSerializer&quot;.
</code></pre>
<p>This error occurs when the Serializer name is "Serializer". You should choose a component's name unique across your schema and different than "Serializer".</p>
<p>You may also get the following warning:</p>
<pre><code>Schema component &quot;ComponentName&quot; has been overriden with a different value.
</code></pre>
<p>This warning occurs when different components have the same name in one schema. Your component name should be unique across your project. This is likely an error that may lead to an invalid schema.</p>
<p>You have two ways to solve the previous issues:</p>
<ul>
<li>You can rename your serializer with a unique name and another name than "Serializer".</li>
<li>You can set the <code>component_name</code> kwarg parameter of the AutoSchema constructor (see below).</li>
<li>You can override the <code>get_component_name</code> method of the AutoSchema class (see below).</li>
</ul>
<h4 id="set-a-custom-components-name-for-your-view"><a class="toclink" href="#set-a-custom-components-name-for-your-view">Set a custom component's name for your view</a></h4>
<p>To override the component's name in your view, you can use the <code>component_name</code> parameter of the AutoSchema constructor:</p>
<pre><code class="python">from rest_framework.schemas.openapi import AutoSchema
class MyView(APIView):
schema = AutoSchema(component_name=&quot;Ulysses&quot;)
</code></pre>
<h4 id="override-the-default-implementation"><a class="toclink" href="#override-the-default-implementation">Override the default implementation</a></h4>
<p>If you want to have more control and customization about how the schema's components are generated, you can override the <code>get_component_name</code> and <code>get_components</code> method from the AutoSchema class.</p>
<pre><code class="python">from rest_framework.schemas.openapi import AutoSchema
class CustomSchema(AutoSchema):
def get_components(self, path, method):
# Implement your custom implementation
def get_component_name(self, serializer):
# Implement your custom implementation
class CustomView(APIView):
&quot;&quot;&quot;APIView subclass with custom schema introspection.&quot;&quot;&quot;
schema = CustomSchema()
</code></pre>
</div> <!--/span-->
</div> <!--/row-->
</div> <!--/.fluid-container-->
</div> <!--/.body content-->
<div id="push"></div>
</div> <!--/.wrapper -->
<footer class="span12">
<p>Documentation built with <a href="http://www.mkdocs.org/">MkDocs</a>.
</p>
</footer>
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script async src="https://fund.django-rest-framework.org/sidebar_include.js"></script>
<script src="../../js/jquery-1.8.1-min.js"></script>
<script src="../../js/prettify-1.0.js"></script>
<script src="../../js/bootstrap-2.1.1-min.js"></script>
<script src="../../js/theme.js"></script>
<script>var base_url = '../..';</script>
<script src="../../search/main.js" defer></script>
<script>
var shiftWindow = function() {
scrollBy(0, -50)
};
if (location.hash) shiftWindow();
window.addEventListener("hashchange", shiftWindow);
$('.dropdown-menu').on('click touchstart', function(event) {
event.stopPropagation();
});
// Dynamically force sidenav/dropdown to no higher than browser window
$('.side-nav, .dropdown-menu').css('max-height', window.innerHeight - 130);
$(function() {
$(window).resize(function() {
$('.side-nav, .dropdown-menu').css('max-height', window.innerHeight - 130);
});
});
</script>
</body>
</html>