Skip to content

Commit

Permalink
Added get_schema_operation_parameters() for DRF OpenAPI schema genera…
Browse files Browse the repository at this point in the history
…tion. (#1086)

* dummy get_schema_operation_parameters() so DRF generateschema won't throw an exception.

* implement get_schema_operation_parameters()

* Updated release note text.
  • Loading branch information
n2ygk authored and carltongibson committed Jul 15, 2019
1 parent fc94eb8 commit c98e52d
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 3 deletions.
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.10+ OpenAPI schema generation.

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()
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

0 comments on commit c98e52d

Please sign in to comment.