mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-07 13:54:47 +03:00
exclude_from_schema
This commit is contained in:
parent
8044d38c21
commit
a8501f72b7
|
@ -127,7 +127,7 @@ REST framework also allows you to work with regular function based views. It pr
|
||||||
|
|
||||||
## @api_view()
|
## @api_view()
|
||||||
|
|
||||||
**Signature:** `@api_view(http_method_names=['GET'])`
|
**Signature:** `@api_view(http_method_names=['GET'], exclude_from_schema=False)`
|
||||||
|
|
||||||
The core of this functionality is the `api_view` decorator, which takes a list of HTTP methods that your view should respond to. For example, this is how you would write a very simple view that just manually returns some data:
|
The core of this functionality is the `api_view` decorator, which takes a list of HTTP methods that your view should respond to. For example, this is how you would write a very simple view that just manually returns some data:
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ The core of this functionality is the `api_view` decorator, which takes a list o
|
||||||
|
|
||||||
This view will use the default renderers, parsers, authentication classes etc specified in the [settings].
|
This view will use the default renderers, parsers, authentication classes etc specified in the [settings].
|
||||||
|
|
||||||
By default only `GET` methods will be accepted. Other methods will respond with "405 Method Not Allowed". To alter this behavior, specify which methods the view allows, like so:
|
By default only `GET` methods will be accepted. Other methods will respond with "405 Method Not Allowed". To alter this behaviour, specify which methods the view allows, like so:
|
||||||
|
|
||||||
@api_view(['GET', 'POST'])
|
@api_view(['GET', 'POST'])
|
||||||
def hello_world(request):
|
def hello_world(request):
|
||||||
|
@ -147,6 +147,13 @@ By default only `GET` methods will be accepted. Other methods will respond with
|
||||||
return Response({"message": "Got some data!", "data": request.data})
|
return Response({"message": "Got some data!", "data": request.data})
|
||||||
return Response({"message": "Hello, world!"})
|
return Response({"message": "Hello, world!"})
|
||||||
|
|
||||||
|
You can also mark an API view as being omitted from any [auto-generated schema][schemas],
|
||||||
|
using the `exclude_from_schema` argument.:
|
||||||
|
|
||||||
|
@api_view(['GET'], exclude_from_schema=True)
|
||||||
|
def api_docs(request):
|
||||||
|
...
|
||||||
|
|
||||||
## API policy decorators
|
## API policy decorators
|
||||||
|
|
||||||
To override the default settings, REST framework provides a set of additional decorators which can be added to your views. These must come *after* (below) the `@api_view` decorator. For example, to create a view that uses a [throttle][throttling] to ensure it can only be called once per day by a particular user, use the `@throttle_classes` decorator, passing a list of throttle classes:
|
To override the default settings, REST framework provides a set of additional decorators which can be added to your views. These must come *after* (below) the `@api_view` decorator. For example, to create a view that uses a [throttle][throttling] to ensure it can only be called once per day by a particular user, use the `@throttle_classes` decorator, passing a list of throttle classes:
|
||||||
|
@ -178,3 +185,4 @@ Each of these decorators takes a single argument which must be a list or tuple o
|
||||||
[cite2]: http://www.boredomandlaziness.org/2012/05/djangos-cbvs-are-not-mistake-but.html
|
[cite2]: http://www.boredomandlaziness.org/2012/05/djangos-cbvs-are-not-mistake-but.html
|
||||||
[settings]: settings.md
|
[settings]: settings.md
|
||||||
[throttling]: throttling.md
|
[throttling]: throttling.md
|
||||||
|
[schemas]: schemas.md
|
||||||
|
|
|
@ -15,7 +15,7 @@ from django.utils import six
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
|
||||||
def api_view(http_method_names=None):
|
def api_view(http_method_names=None, exclude_from_schema=False):
|
||||||
"""
|
"""
|
||||||
Decorator that converts a function-based view into an APIView subclass.
|
Decorator that converts a function-based view into an APIView subclass.
|
||||||
Takes a list of allowed methods for the view as an argument.
|
Takes a list of allowed methods for the view as an argument.
|
||||||
|
@ -72,6 +72,7 @@ def api_view(http_method_names=None):
|
||||||
WrappedAPIView.permission_classes = getattr(func, 'permission_classes',
|
WrappedAPIView.permission_classes = getattr(func, 'permission_classes',
|
||||||
APIView.permission_classes)
|
APIView.permission_classes)
|
||||||
|
|
||||||
|
WrappedAPIView.exclude_from_schema = exclude_from_schema
|
||||||
return WrappedAPIView.as_view()
|
return WrappedAPIView.as_view()
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,7 @@ class DefaultRouter(SimpleRouter):
|
||||||
|
|
||||||
class APISchemaView(views.APIView):
|
class APISchemaView(views.APIView):
|
||||||
_ignore_model_permissions = True
|
_ignore_model_permissions = True
|
||||||
|
exclude_from_schema = True
|
||||||
renderer_classes = schema_renderers
|
renderer_classes = schema_renderers
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
@ -332,6 +333,7 @@ class DefaultRouter(SimpleRouter):
|
||||||
|
|
||||||
class APIRootView(views.APIView):
|
class APIRootView(views.APIView):
|
||||||
_ignore_model_permissions = True
|
_ignore_model_permissions = True
|
||||||
|
exclude_from_schema = True
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# Return a plain {"name": "hyperlink"} response.
|
# Return a plain {"name": "hyperlink"} response.
|
||||||
|
|
|
@ -56,6 +56,22 @@ def is_custom_action(action):
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def is_list_view(path, method, view):
|
||||||
|
"""
|
||||||
|
Return True if the given path/method appears to represent a list view.
|
||||||
|
"""
|
||||||
|
if hasattr(view, 'action'):
|
||||||
|
# Viewsets have an explicitly defined action, which we can inspect.
|
||||||
|
return view.action == 'list'
|
||||||
|
|
||||||
|
if method.lower() != 'get':
|
||||||
|
return False
|
||||||
|
path_components = path.strip('/').split('/')
|
||||||
|
if path_components and '{' in path_components[-1]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def endpoint_ordering(endpoint):
|
def endpoint_ordering(endpoint):
|
||||||
path, method, callback = endpoint
|
path, method, callback = endpoint
|
||||||
method_priority = {
|
method_priority = {
|
||||||
|
@ -136,9 +152,6 @@ class EndpointInspector(object):
|
||||||
if path.endswith('.{format}') or path.endswith('.{format}/'):
|
if path.endswith('.{format}') or path.endswith('.{format}/'):
|
||||||
return False # Ignore .json style URLs.
|
return False # Ignore .json style URLs.
|
||||||
|
|
||||||
if path == '/':
|
|
||||||
return False # Ignore the root endpoint.
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_allowed_methods(self, callback):
|
def get_allowed_methods(self, callback):
|
||||||
|
@ -201,7 +214,7 @@ class SchemaGenerator(object):
|
||||||
links = OrderedDict()
|
links = OrderedDict()
|
||||||
for path, method, callback in self.endpoints:
|
for path, method, callback in self.endpoints:
|
||||||
view = self.create_view(callback, method, request)
|
view = self.create_view(callback, method, request)
|
||||||
if not self.has_view_permissions(view):
|
if not self.should_include_view(path, method, view):
|
||||||
continue
|
continue
|
||||||
link = self.get_link(path, method, view)
|
link = self.get_link(path, method, view)
|
||||||
keys = self.get_keys(path, method, view)
|
keys = self.get_keys(path, method, view)
|
||||||
|
@ -235,10 +248,13 @@ class SchemaGenerator(object):
|
||||||
|
|
||||||
return view
|
return view
|
||||||
|
|
||||||
def has_view_permissions(self, view):
|
def should_include_view(self, path, method, view):
|
||||||
"""
|
"""
|
||||||
Return `True` if the incoming request has the correct view permissions.
|
Return `True` if the incoming request has the correct view permissions.
|
||||||
"""
|
"""
|
||||||
|
if getattr(view, 'exclude_from_schema', False):
|
||||||
|
return False
|
||||||
|
|
||||||
if view.request is None:
|
if view.request is None:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -248,20 +264,6 @@ class SchemaGenerator(object):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def is_list_endpoint(self, path, method, view):
|
|
||||||
"""
|
|
||||||
Return True if the given path/method appears to represent a list endpoint.
|
|
||||||
"""
|
|
||||||
if hasattr(view, 'action'):
|
|
||||||
return view.action == 'list'
|
|
||||||
|
|
||||||
if method.lower() != 'get':
|
|
||||||
return False
|
|
||||||
path_components = path.strip('/').split('/')
|
|
||||||
if path_components and '{' in path_components[-1]:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Methods for generating each individual `Link` instance...
|
# Methods for generating each individual `Link` instance...
|
||||||
|
|
||||||
def get_link(self, path, method, view):
|
def get_link(self, path, method, view):
|
||||||
|
@ -359,7 +361,7 @@ class SchemaGenerator(object):
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
def get_pagination_fields(self, path, method, view):
|
def get_pagination_fields(self, path, method, view):
|
||||||
if not self.is_list_endpoint(path, method, view):
|
if not is_list_view(path, method, view):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if not getattr(view, 'pagination_class', None):
|
if not getattr(view, 'pagination_class', None):
|
||||||
|
@ -369,7 +371,7 @@ class SchemaGenerator(object):
|
||||||
return as_query_fields(paginator.get_fields(view))
|
return as_query_fields(paginator.get_fields(view))
|
||||||
|
|
||||||
def get_filter_fields(self, path, method, view):
|
def get_filter_fields(self, path, method, view):
|
||||||
if not self.is_list_endpoint(path, method, view):
|
if not is_list_view(path, method, view):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if not getattr(view, 'filter_backends', None):
|
if not getattr(view, 'filter_backends', None):
|
||||||
|
@ -402,7 +404,7 @@ class SchemaGenerator(object):
|
||||||
action = view.action
|
action = view.action
|
||||||
else:
|
else:
|
||||||
# Views have no associated action, so we determine one from the method.
|
# Views have no associated action, so we determine one from the method.
|
||||||
if self.is_list_endpoint(path, method, view):
|
if is_list_view(path, method, view):
|
||||||
action = 'list'
|
action = 'list'
|
||||||
else:
|
else:
|
||||||
action = self.default_mapping[method.lower()]
|
action = self.default_mapping[method.lower()]
|
||||||
|
|
|
@ -110,6 +110,9 @@ class APIView(View):
|
||||||
# Allow dependency injection of other settings to make testing easier.
|
# Allow dependency injection of other settings to make testing easier.
|
||||||
settings = api_settings
|
settings = api_settings
|
||||||
|
|
||||||
|
# Mark the view as being included or excluded from schema generation.
|
||||||
|
exclude_from_schema = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def as_view(cls, **initkwargs):
|
def as_view(cls, **initkwargs):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user