Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add get_schema_operation_parameters() for Open API 3 generateschema #1086

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Version 2.x (unreleased)
------------------------

* Added ``DjangoFilterBackend.get_schema_operation_parameters()`` for DRF 3.9+ ``generateschema``.

Version 2.1 (2019-1-20)
-----------------------

Expand Down
22 changes: 22 additions & 0 deletions django_filters/rest_framework/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,25 @@ def get_schema_fields(self, view):
schema=self.get_coreschema_field(field)
) for field_name, field in filterset_class.base_filters.items()
]

def get_schema_operation_parameters(self, view):
try:
queryset = view.get_queryset()
n2ygk marked this conversation as resolved.
Show resolved Hide resolved
except Exception:
queryset = None
warnings.warn(
"{} is not compatible with schema generation".format(view.__class__)
)

filterset_class = self.get_filterset_class(view, queryset)
return [] if not filterset_class else [
({
'name': field_name,
'required': field.extra['required'],
'in': 'query',
'description': field.label if field.label is not None else field_name,
'schema': {
'type': 'string',
},
}) for field_name, field in filterset_class.base_filters.items()
]
6 changes: 3 additions & 3 deletions docs/guide/rest_framework.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ You can override these methods on a case-by-case basis for each view, creating u
'author': self.get_author(),
}

Schema Generation with Core API
-------------------------------
Schema Generation with Core API and Open API
--------------------------------------------

The backend class integrates with DRF's schema generation by implementing ``get_schema_fields()``. This is automatically enabled when Core API is installed. Schema generation usually functions seamlessly, however the implementation does expect to invoke the view's ``get_queryset()`` method. There is a caveat in that views are artificially constructed during schema generation, so the ``args`` and ``kwargs`` attributes will be empty. If you depend on arguments parsed from the URL, you will need to handle their absence in ``get_queryset()``.
The backend class integrates with DRF's schema generation by implementing ``get_schema_fields()`` and ``get_schema_operation_parameters()``. ``get_schema_fields()`` is automatically enabled when Core API is installed. ``get_schema_operation_parameters()`` is always enabled for Open API (new since DRF 3.9). Schema generation usually functions seamlessly, however the implementation does expect to invoke the view's ``get_queryset()`` method. There is a caveat in that views are artificially constructed during schema generation, so the ``args`` and ``kwargs`` attributes will be empty. If you depend on arguments parsed from the URL, you will need to handle their absence in ``get_queryset()``.

For example, your get queryset method may look like this:

Expand Down
9 changes: 9 additions & 0 deletions tests/rest_framework/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ class View(FilterClassRootView):
self.assertEqual(fields, ['text', 'decimal', 'date', 'f'])


class GetSchemaOperationParametersTests(TestCase):
def test_get_operation_parameters_with_filterset_fields_list(self):
backend = DjangoFilterBackend()
fields = backend.get_schema_operation_parameters(FilterFieldsRootView())
fields = [f['name'] for f in fields]

self.assertEqual(fields, ['decimal', 'date'])


class TemplateTests(TestCase):
def test_backend_output(self):
"""
Expand Down