mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-07 13:54:47 +03:00
Added 'get_schema_view()' shortcut
This commit is contained in:
parent
a8501f72b7
commit
cd826ce422
|
@ -102,15 +102,20 @@ REST framework includes functionality for auto-generating a schema,
|
||||||
or allows you to specify one explicitly. There are a few different ways to
|
or allows you to specify one explicitly. There are a few different ways to
|
||||||
add a schema to your API, depending on exactly what you need.
|
add a schema to your API, depending on exactly what you need.
|
||||||
|
|
||||||
## Using DefaultRouter
|
## The get_schema_view shortcut
|
||||||
|
|
||||||
If you're using `DefaultRouter` then you can include an auto-generated schema,
|
The simplest way to include a schema in your project is to use the
|
||||||
simply by adding a `schema_title` argument to the router.
|
`get_schema_view()` function.
|
||||||
|
|
||||||
router = DefaultRouter(schema_title='Server Monitoring API')
|
schema_view = get_schema_view(title="Server Monitoring API")
|
||||||
|
|
||||||
The schema will be included at the root URL, `/`, and presented to clients
|
urlpatterns = [
|
||||||
that include the Core JSON media type in their `Accept` header.
|
url('^$', schema_view),
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
Once the view has been added, you'll be able to make API requests to retrieve
|
||||||
|
the auto-generated schema definition.
|
||||||
|
|
||||||
$ http http://127.0.0.1:8000/ Accept:application/vnd.coreapi+json
|
$ http http://127.0.0.1:8000/ Accept:application/vnd.coreapi+json
|
||||||
HTTP/1.0 200 OK
|
HTTP/1.0 200 OK
|
||||||
|
@ -125,48 +130,43 @@ that include the Core JSON media type in their `Accept` header.
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
This is a great zero-configuration option for when you want to get up and
|
The arguments to `get_schema_view()` are:
|
||||||
running really quickly.
|
|
||||||
|
|
||||||
The other available options to `DefaultRouter` are:
|
#### `title`
|
||||||
|
|
||||||
#### schema_renderers
|
May be used to provide a descriptive title for the schema definition.
|
||||||
|
|
||||||
May be used to pass the set of renderer classes that can be used to render schema output.
|
#### `url`
|
||||||
|
|
||||||
|
May be used to pass a canonical URL for the schema.
|
||||||
|
|
||||||
|
schema_view = get_schema_view(
|
||||||
|
title='Server Monitoring API',
|
||||||
|
url='https://www.example.org/api/'
|
||||||
|
)
|
||||||
|
|
||||||
|
#### `renderer_classes`
|
||||||
|
|
||||||
|
May be used to pass the set of renderer classes that can be used to render the API root endpoint.
|
||||||
|
|
||||||
from rest_framework.renderers import CoreJSONRenderer
|
from rest_framework.renderers import CoreJSONRenderer
|
||||||
from my_custom_package import APIBlueprintRenderer
|
from my_custom_package import APIBlueprintRenderer
|
||||||
|
|
||||||
router = DefaultRouter(schema_title='Server Monitoring API', schema_renderers=[
|
schema_view = get_schema_view(
|
||||||
CoreJSONRenderer, APIBlueprintRenderer
|
title='Server Monitoring API',
|
||||||
])
|
url='https://www.example.org/api/',
|
||||||
|
renderer_classes=[CoreJSONRenderer, APIBlueprintRenderer]
|
||||||
#### schema_url
|
|
||||||
|
|
||||||
May be used to pass the root URL for the schema. This can either be used to ensure that
|
|
||||||
the schema URLs include a canonical hostname and schema, or to ensure that all the
|
|
||||||
schema URLs include a path prefix.
|
|
||||||
|
|
||||||
router = DefaultRouter(
|
|
||||||
schema_title='Server Monitoring API',
|
|
||||||
schema_url='https://www.example.org/api/'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
If you want more flexibility over the schema output then you'll need to consider
|
## Using an explicit schema view
|
||||||
using `SchemaGenerator` instead.
|
|
||||||
|
|
||||||
#### root_renderers
|
If you need a little more control than the `get_schema_view()` shortcut gives you,
|
||||||
|
then you can use the `SchemaGenerator` class directly to auto-generate the
|
||||||
May be used to pass the set of renderer classes that can be used to render the API root endpoint.
|
`Document` instance, and to return that from a view.
|
||||||
|
|
||||||
## Using SchemaGenerator
|
|
||||||
|
|
||||||
The most common way to add a schema to your API is to use the `SchemaGenerator`
|
|
||||||
class to auto-generate the `Document` instance, and to return that from a view.
|
|
||||||
|
|
||||||
This option gives you the flexibility of setting up the schema endpoint
|
This option gives you the flexibility of setting up the schema endpoint
|
||||||
with whatever behavior you want. For example, you can apply different
|
with whatever behaviour you want. For example, you can apply different
|
||||||
permission, throttling or authentication policies to the schema endpoint.
|
permission, throttling, or authentication policies to the schema endpoint.
|
||||||
|
|
||||||
Here's an example of using `SchemaGenerator` together with a view to
|
Here's an example of using `SchemaGenerator` together with a view to
|
||||||
return the schema.
|
return the schema.
|
||||||
|
@ -176,12 +176,13 @@ return the schema.
|
||||||
from rest_framework.decorators import api_view, renderer_classes
|
from rest_framework.decorators import api_view, renderer_classes
|
||||||
from rest_framework import renderers, response, schemas
|
from rest_framework import renderers, response, schemas
|
||||||
|
|
||||||
|
generator = schemas.SchemaGenerator(title='Bookings API')
|
||||||
|
|
||||||
@api_view()
|
@api_view()
|
||||||
@renderer_classes([renderers.CoreJSONRenderer])
|
@renderer_classes([renderers.CoreJSONRenderer])
|
||||||
def schema_view(request):
|
def schema_view(request):
|
||||||
generator = schemas.SchemaGenerator(title='Bookings API')
|
schema = generator.get_schema(request)
|
||||||
return response.Response(generator.get_schema())
|
return response.Response(schema)
|
||||||
|
|
||||||
**urls.py:**
|
**urls.py:**
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,17 @@ API schema.
|
||||||
|
|
||||||
$ pip install coreapi
|
$ pip install coreapi
|
||||||
|
|
||||||
We can now include a schema for our API, by adding a `schema_title` argument to
|
We can now include a schema for our API, by including an autogenerated schema
|
||||||
the router instantiation.
|
view in our URL configuration.
|
||||||
|
|
||||||
router = DefaultRouter(schema_title='Pastebin API')
|
from rest_framework.schemas import get_schema_view
|
||||||
|
|
||||||
|
schema_view = get_schema_view(title='Pastebin API')
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url('^schema/$', schema_view),
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
If you visit the API root endpoint in a browser you should now see `corejson`
|
If you visit the API root endpoint in a browser you should now see `corejson`
|
||||||
representation become available as an option.
|
representation become available as an option.
|
||||||
|
@ -46,7 +53,7 @@ representation become available as an option.
|
||||||
We can also request the schema from the command line, by specifying the desired
|
We can also request the schema from the command line, by specifying the desired
|
||||||
content type in the `Accept` header.
|
content type in the `Accept` header.
|
||||||
|
|
||||||
$ http http://127.0.0.1:8000/ Accept:application/vnd.coreapi+json
|
$ http http://127.0.0.1:8000/schema/ Accept:application/vnd.coreapi+json
|
||||||
HTTP/1.0 200 OK
|
HTTP/1.0 200 OK
|
||||||
Allow: GET, HEAD, OPTIONS
|
Allow: GET, HEAD, OPTIONS
|
||||||
Content-Type: application/vnd.coreapi+json
|
Content-Type: application/vnd.coreapi+json
|
||||||
|
@ -91,8 +98,8 @@ Now check that it is available on the command line...
|
||||||
|
|
||||||
First we'll load the API schema using the command line client.
|
First we'll load the API schema using the command line client.
|
||||||
|
|
||||||
$ coreapi get http://127.0.0.1:8000/
|
$ coreapi get http://127.0.0.1:8000/schema/
|
||||||
<Pastebin API "http://127.0.0.1:8000/">
|
<Pastebin API "http://127.0.0.1:8000/schema/">
|
||||||
snippets: {
|
snippets: {
|
||||||
highlight(pk)
|
highlight(pk)
|
||||||
list()
|
list()
|
||||||
|
@ -150,7 +157,7 @@ Now if we fetch the schema again, we should be able to see the full
|
||||||
set of available interactions.
|
set of available interactions.
|
||||||
|
|
||||||
$ coreapi reload
|
$ coreapi reload
|
||||||
Pastebin API "http://127.0.0.1:8000/">
|
Pastebin API "http://127.0.0.1:8000/schema/">
|
||||||
snippets: {
|
snippets: {
|
||||||
create(code, [title], [linenos], [language], [style])
|
create(code, [title], [linenos], [language], [style])
|
||||||
destroy(pk)
|
destroy(pk)
|
||||||
|
|
|
@ -6,11 +6,13 @@ from django.contrib.admindocs.views import simplify_regex
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
from rest_framework import exceptions, serializers
|
from rest_framework import exceptions, renderers, serializers
|
||||||
from rest_framework.compat import (
|
from rest_framework.compat import (
|
||||||
RegexURLPattern, RegexURLResolver, coreapi, uritemplate, urlparse
|
RegexURLPattern, RegexURLResolver, coreapi, uritemplate, urlparse
|
||||||
)
|
)
|
||||||
from rest_framework.request import clone_request
|
from rest_framework.request import clone_request
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.settings import api_settings
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,15 +94,14 @@ class EndpointInspector(object):
|
||||||
if patterns is None:
|
if patterns is None:
|
||||||
if urlconf is None:
|
if urlconf is None:
|
||||||
# Use the default Django URL conf
|
# Use the default Django URL conf
|
||||||
urls = import_module(settings.ROOT_URLCONF)
|
urlconf = settings.ROOT_URLCONF
|
||||||
patterns = urls.urlpatterns
|
|
||||||
|
# Load the given URLconf module
|
||||||
|
if isinstance(urlconf, six.string_types):
|
||||||
|
urls = import_module(urlconf)
|
||||||
else:
|
else:
|
||||||
# Load the given URLconf module
|
urls = urlconf
|
||||||
if isinstance(urlconf, six.string_types):
|
patterns = urls.urlpatterns
|
||||||
urls = import_module(urlconf)
|
|
||||||
else:
|
|
||||||
urls = urlconf
|
|
||||||
patterns = urls.urlpatterns
|
|
||||||
|
|
||||||
self.patterns = patterns
|
self.patterns = patterns
|
||||||
|
|
||||||
|
@ -189,7 +190,8 @@ class SchemaGenerator(object):
|
||||||
if url and not url.endswith('/'):
|
if url and not url.endswith('/'):
|
||||||
url += '/'
|
url += '/'
|
||||||
|
|
||||||
self.endpoint_inspector = self.endpoint_inspector_cls(patterns, urlconf)
|
self.patterns = patterns
|
||||||
|
self.urlconf = urlconf
|
||||||
self.title = title
|
self.title = title
|
||||||
self.url = url
|
self.url = url
|
||||||
self.endpoints = None
|
self.endpoints = None
|
||||||
|
@ -199,7 +201,8 @@ class SchemaGenerator(object):
|
||||||
Generate a `coreapi.Document` representing the API schema.
|
Generate a `coreapi.Document` representing the API schema.
|
||||||
"""
|
"""
|
||||||
if self.endpoints is None:
|
if self.endpoints is None:
|
||||||
self.endpoints = self.endpoint_inspector.get_api_endpoints()
|
inspector = self.endpoint_inspector_cls(self.patterns, self.urlconf)
|
||||||
|
self.endpoints = inspector.get_api_endpoints()
|
||||||
|
|
||||||
links = self.get_links(request)
|
links = self.get_links(request)
|
||||||
if not links:
|
if not links:
|
||||||
|
@ -425,3 +428,30 @@ class SchemaGenerator(object):
|
||||||
|
|
||||||
# Default action, eg "/users/", "/users/{pk}/"
|
# Default action, eg "/users/", "/users/{pk}/"
|
||||||
return named_path_components + [action]
|
return named_path_components + [action]
|
||||||
|
|
||||||
|
|
||||||
|
def get_schema_view(title=None, url=None, renderer_classes=None):
|
||||||
|
"""
|
||||||
|
Return a schema view.
|
||||||
|
"""
|
||||||
|
generator = SchemaGenerator(title=title, url=url)
|
||||||
|
if renderer_classes is None:
|
||||||
|
if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
|
||||||
|
rclasses = [renderers.CoreJSONRenderer, renderers.BrowsableAPIRenderer]
|
||||||
|
else:
|
||||||
|
rclasses = [renderers.CoreJSONRenderer]
|
||||||
|
else:
|
||||||
|
rclasses = renderer_classes
|
||||||
|
|
||||||
|
class SchemaView(APIView):
|
||||||
|
_ignore_model_permissions = True
|
||||||
|
exclude_from_schema = True
|
||||||
|
renderer_classes = rclasses
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
schema = generator.get_schema(request)
|
||||||
|
if schema is None:
|
||||||
|
raise exceptions.PermissionDenied()
|
||||||
|
return Response(schema)
|
||||||
|
|
||||||
|
return SchemaView.as_view()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user