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()
|
||||
|
||||
**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:
|
||||
|
||||
|
@ -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].
|
||||
|
||||
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'])
|
||||
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": "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
|
||||
|
||||
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
|
||||
[settings]: settings.md
|
||||
[throttling]: throttling.md
|
||||
[schemas]: schemas.md
|
||||
|
|
|
@ -15,7 +15,7 @@ from django.utils import six
|
|||
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.
|
||||
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',
|
||||
APIView.permission_classes)
|
||||
|
||||
WrappedAPIView.exclude_from_schema = exclude_from_schema
|
||||
return WrappedAPIView.as_view()
|
||||
return decorator
|
||||
|
||||
|
|
|
@ -311,6 +311,7 @@ class DefaultRouter(SimpleRouter):
|
|||
|
||||
class APISchemaView(views.APIView):
|
||||
_ignore_model_permissions = True
|
||||
exclude_from_schema = True
|
||||
renderer_classes = schema_renderers
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
@ -332,6 +333,7 @@ class DefaultRouter(SimpleRouter):
|
|||
|
||||
class APIRootView(views.APIView):
|
||||
_ignore_model_permissions = True
|
||||
exclude_from_schema = True
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
# 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):
|
||||
path, method, callback = endpoint
|
||||
method_priority = {
|
||||
|
@ -136,9 +152,6 @@ class EndpointInspector(object):
|
|||
if path.endswith('.{format}') or path.endswith('.{format}/'):
|
||||
return False # Ignore .json style URLs.
|
||||
|
||||
if path == '/':
|
||||
return False # Ignore the root endpoint.
|
||||
|
||||
return True
|
||||
|
||||
def get_allowed_methods(self, callback):
|
||||
|
@ -201,7 +214,7 @@ class SchemaGenerator(object):
|
|||
links = OrderedDict()
|
||||
for path, method, callback in self.endpoints:
|
||||
view = self.create_view(callback, method, request)
|
||||
if not self.has_view_permissions(view):
|
||||
if not self.should_include_view(path, method, view):
|
||||
continue
|
||||
link = self.get_link(path, method, view)
|
||||
keys = self.get_keys(path, method, view)
|
||||
|
@ -235,10 +248,13 @@ class SchemaGenerator(object):
|
|||
|
||||
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.
|
||||
"""
|
||||
if getattr(view, 'exclude_from_schema', False):
|
||||
return False
|
||||
|
||||
if view.request is None:
|
||||
return True
|
||||
|
||||
|
@ -248,20 +264,6 @@ class SchemaGenerator(object):
|
|||
return False
|
||||
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...
|
||||
|
||||
def get_link(self, path, method, view):
|
||||
|
@ -359,7 +361,7 @@ class SchemaGenerator(object):
|
|||
return fields
|
||||
|
||||
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 []
|
||||
|
||||
if not getattr(view, 'pagination_class', None):
|
||||
|
@ -369,7 +371,7 @@ class SchemaGenerator(object):
|
|||
return as_query_fields(paginator.get_fields(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 []
|
||||
|
||||
if not getattr(view, 'filter_backends', None):
|
||||
|
@ -402,7 +404,7 @@ class SchemaGenerator(object):
|
|||
action = view.action
|
||||
else:
|
||||
# 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'
|
||||
else:
|
||||
action = self.default_mapping[method.lower()]
|
||||
|
|
|
@ -110,6 +110,9 @@ class APIView(View):
|
|||
# Allow dependency injection of other settings to make testing easier.
|
||||
settings = api_settings
|
||||
|
||||
# Mark the view as being included or excluded from schema generation.
|
||||
exclude_from_schema = False
|
||||
|
||||
@classmethod
|
||||
def as_view(cls, **initkwargs):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user