parent
a3e81ef7f6
commit
a211184478
|
|
@ -9,6 +9,31 @@ Custom schema generation
|
||||||
If the default spec generation does not quite match what you were hoping to achieve, ``drf-yasg`` provides some
|
If the default spec generation does not quite match what you were hoping to achieve, ``drf-yasg`` provides some
|
||||||
custom behavior hooks by default.
|
custom behavior hooks by default.
|
||||||
|
|
||||||
|
.. _custom-spec-excluding-endpoints:
|
||||||
|
|
||||||
|
*******************
|
||||||
|
Excluding endpoints
|
||||||
|
*******************
|
||||||
|
|
||||||
|
You can prevent a view from being included in the Swagger view by setting its class-level ``swagger_schema``
|
||||||
|
attribute to ``None``, or you can prevent an operation from being included by setting its ``auto_schema`` override
|
||||||
|
to none in :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
class UserList(APIView):
|
||||||
|
swagger_schema = None
|
||||||
|
|
||||||
|
# all methods of the UserList class will be excluded
|
||||||
|
...
|
||||||
|
|
||||||
|
# only the GET method will be shown in Swagger
|
||||||
|
@swagger_auto_schema(method='put', auto_schema=None)
|
||||||
|
@swagger_auto_schema(methods=['get'], ...)
|
||||||
|
@api_view(['GET', 'PUT'])
|
||||||
|
def user_detail(request, pk):
|
||||||
|
pass
|
||||||
|
|
||||||
.. _custom-spec-swagger-auto-schema:
|
.. _custom-spec-swagger-auto-schema:
|
||||||
|
|
||||||
**************************************
|
**************************************
|
||||||
|
|
@ -200,8 +225,6 @@ This custom generator can be put to use by setting it as the :attr:`.generator_c
|
||||||
``Inspector`` classes
|
``Inspector`` classes
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
.. versionadded:: 1.1
|
|
||||||
|
|
||||||
For customizing behavior related to specific field, serializer, filter or paginator classes you can implement the
|
For customizing behavior related to specific field, serializer, filter or paginator classes you can implement the
|
||||||
:class:`~.inspectors.FieldInspector`, :class:`~.inspectors.SerializerInspector`, :class:`~.inspectors.FilterInspector`,
|
:class:`~.inspectors.FieldInspector`, :class:`~.inspectors.SerializerInspector`, :class:`~.inspectors.FilterInspector`,
|
||||||
:class:`~.inspectors.PaginatorInspector` classes and use them with
|
:class:`~.inspectors.PaginatorInspector` classes and use them with
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
Functional overview
|
Functional overview
|
||||||
**********************
|
**********************
|
||||||
|
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
OpenAPI specification overview
|
OpenAPI specification overview
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
@ -155,9 +154,26 @@ This section describes where information is sourced from when using the default
|
||||||
|
|
||||||
Other versioning schemes are not presently supported.
|
Other versioning schemes are not presently supported.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
A note on limitations
|
||||||
|
---------------------
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
When schema generation is requested, available endpoints are inspected by enumeration all the routes registered in
|
||||||
Base path and versioning support.
|
Django's urlconf. Each registered view is then artificially instantiated for introspection, and it is this step that
|
||||||
|
brings some limitations to what can be done:
|
||||||
|
|
||||||
|
* the ``request`` the view sees will always be the request made against the schema view endpoint
|
||||||
|
- e.g. ``GET /swagger.yaml``
|
||||||
|
* path parameters will not be filled
|
||||||
|
|
||||||
|
This means that you could get surprizing results if your ``get_serializer`` or ``get_serializer_class`` methods
|
||||||
|
depend on the incoming request, call ``get_object`` or in general depend on any stateful logic. You can prevent this
|
||||||
|
in a few ways:
|
||||||
|
|
||||||
|
* provide a fixed serializer for request and response body introspection using
|
||||||
|
:ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`, to prevent ``get_serializer`` from being called on
|
||||||
|
the view
|
||||||
|
* :ref:`exclude your endpoint from introspection <custom-spec-excluding-endpoints>`
|
||||||
|
|
||||||
.. _SCRIPT_NAME: https://www.python.org/dev/peps/pep-0333/#environ-variables
|
.. _SCRIPT_NAME: https://www.python.org/dev/peps/pep-0333/#environ-variables
|
||||||
.. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name
|
.. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,6 @@ You can use your custom renderer classes as kwargs to :meth:`.SchemaView.as_cach
|
||||||
Management command
|
Management command
|
||||||
******************
|
******************
|
||||||
|
|
||||||
.. versionadded:: 1.1.1
|
|
||||||
|
|
||||||
If you only need a swagger spec file in YAML or JSON format, you can use the ``generate_swagger`` management command
|
If you only need a swagger spec file in YAML or JSON format, you can use the ``generate_swagger`` management command
|
||||||
to get it without having to start the web server:
|
to get it without having to start the web server:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@ class EndpointEnumerator(_EndpointEnumerator):
|
||||||
if version and version not in namespace.split(':'):
|
if version and version not in namespace.split(':'):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if getattr(callback.cls, 'swagger_schema', object()) is None:
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def replace_version(self, path, callback):
|
def replace_version(self, path, callback):
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ class SwaggerAutoSchema(ViewInspector):
|
||||||
if body_override is no_body:
|
if body_override is no_body:
|
||||||
return None
|
return None
|
||||||
if self.method not in self.body_methods:
|
if self.method not in self.body_methods:
|
||||||
raise SwaggerGenerationError("request_body can only be applied to PUT, PATCH or POST views; "
|
raise SwaggerGenerationError("request_body can only be applied to (" + ','.join(self.body_methods) +
|
||||||
"are you looking for query_serializer or manual_parameters?")
|
"); are you looking for query_serializer or manual_parameters?")
|
||||||
if isinstance(body_override, openapi.Schema.OR_REF):
|
if isinstance(body_override, openapi.Schema.OR_REF):
|
||||||
return body_override
|
return body_override
|
||||||
return force_serializer_instance(body_override)
|
return force_serializer_instance(body_override)
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ logger = logging.getLogger(__name__)
|
||||||
#: used to forcibly remove the body of a request via :func:`.swagger_auto_schema`
|
#: used to forcibly remove the body of a request via :func:`.swagger_auto_schema`
|
||||||
no_body = object()
|
no_body = object()
|
||||||
|
|
||||||
|
unset = object()
|
||||||
|
|
||||||
def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_body=None, query_serializer=None,
|
|
||||||
|
def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_body=None, query_serializer=None,
|
||||||
manual_parameters=None, operation_id=None, operation_description=None, security=None,
|
manual_parameters=None, operation_id=None, operation_description=None, security=None,
|
||||||
responses=None, field_inspectors=None, filter_inspectors=None, paginator_inspectors=None,
|
responses=None, field_inspectors=None, filter_inspectors=None, paginator_inspectors=None,
|
||||||
**extra_overrides):
|
**extra_overrides):
|
||||||
|
|
@ -24,17 +26,11 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||||
|
|
||||||
The `auto_schema` and `operation_description` arguments take precendence over view- or method-level values.
|
The `auto_schema` and `operation_description` arguments take precendence over view- or method-level values.
|
||||||
|
|
||||||
.. versionchanged:: 1.1
|
|
||||||
Added the ``extra_overrides`` and ``operatiod_id`` parameters.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.1
|
|
||||||
Added the ``field_inspectors``, ``filter_inspectors`` and ``paginator_inspectors`` parameters.
|
|
||||||
|
|
||||||
:param str method: for multi-method views, the http method the options should apply to
|
:param str method: for multi-method views, the http method the options should apply to
|
||||||
:param list[str] methods: for multi-method views, the http methods the options should apply to
|
:param list[str] methods: for multi-method views, the http methods the options should apply to
|
||||||
:param .inspectors.SwaggerAutoSchema auto_schema: custom class to use for generating the Operation object;
|
:param .inspectors.SwaggerAutoSchema auto_schema: custom class to use for generating the Operation object;
|
||||||
this overrides both the class-level ``swagger_schema`` attribute and the ``DEFAULT_AUTO_SCHEMA_CLASS``
|
this overrides both the class-level ``swagger_schema`` attribute and the ``DEFAULT_AUTO_SCHEMA_CLASS``
|
||||||
setting
|
setting, and can be set to ``None`` to prevent this operation from being generated
|
||||||
:param .Schema,.SchemaRef,.Serializer request_body: custom request body, or :data:`.no_body`. The value given here
|
:param .Schema,.SchemaRef,.Serializer request_body: custom request body, or :data:`.no_body`. The value given here
|
||||||
will be used as the ``schema`` property of a :class:`.Parameter` with ``in: 'body'``.
|
will be used as the ``schema`` property of a :class:`.Parameter` with ``in: 'body'``.
|
||||||
|
|
||||||
|
|
@ -92,7 +88,6 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||||
def decorator(view_method):
|
def decorator(view_method):
|
||||||
assert not any(hm in extra_overrides for hm in APIView.http_method_names), "HTTP method names not allowed here"
|
assert not any(hm in extra_overrides for hm in APIView.http_method_names), "HTTP method names not allowed here"
|
||||||
data = {
|
data = {
|
||||||
'auto_schema': auto_schema,
|
|
||||||
'request_body': request_body,
|
'request_body': request_body,
|
||||||
'query_serializer': query_serializer,
|
'query_serializer': query_serializer,
|
||||||
'manual_parameters': manual_parameters,
|
'manual_parameters': manual_parameters,
|
||||||
|
|
@ -105,6 +100,8 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||||
'field_inspectors': list(field_inspectors) if field_inspectors else None,
|
'field_inspectors': list(field_inspectors) if field_inspectors else None,
|
||||||
}
|
}
|
||||||
data = filter_none(data)
|
data = filter_none(data)
|
||||||
|
if auto_schema is not unset:
|
||||||
|
data['auto_schema'] = auto_schema
|
||||||
data.update(extra_overrides)
|
data.update(extra_overrides)
|
||||||
if not data: # pragma: no cover
|
if not data: # pragma: no cover
|
||||||
# no overrides to set, no use in doing more work
|
# no overrides to set, no use in doing more work
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue