Skip to content

implement DjangoFilterBackend.get_schema_operation_parameters #646

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

Closed
Show file tree
Hide file tree
Changes from all 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
57 changes: 57 additions & 0 deletions example/tests/unit/test_openapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from rest_framework import filters as drf_filters

from rest_framework_json_api import filters as dja_filters
from rest_framework_json_api.django_filters import backends

from example.views import EntryViewSet


class DummyEntryViewSet(EntryViewSet):
filter_backends = (dja_filters.QueryParameterValidationFilter, dja_filters.OrderingFilter,
backends.DjangoFilterBackend, drf_filters.SearchFilter)
filterset_fields = {
'id': ('exact',),
'headline': ('exact',),
}


def test_filters_get_schema_params():
"""
test all my filters for `get_schema_operation_parameters()`
"""
# list of tuples: (filter, expected result)
filters = [
(dja_filters.QueryParameterValidationFilter, []),
(backends.DjangoFilterBackend, [
{
'name': 'filter[id]', 'required': False, 'in': 'query',
'description': 'id', 'schema': {'type': 'string'}
},
{
'name': 'filter[headline]', 'required': False, 'in': 'query',
'description': 'headline', 'schema': {'type': 'string'}
}
]),
(dja_filters.OrderingFilter, [
{
'name': 'sort', 'required': False, 'in': 'query',
'description': 'Which field to use when ordering the results.',
'schema': {'type': 'string'}
}
]),
(drf_filters.SearchFilter, [
{
'name': 'filter[search]', 'required': False, 'in': 'query',
'description': 'A search term.',
'schema': {'type': 'string'}
}
]),
]
view = DummyEntryViewSet()

for c, expected in filters:
f = c()
# get_schema_operation_parameters is only available in DRF >= 3.10
if hasattr(f, 'get_schema_operation_parameters'):
result = f.get_schema_operation_parameters(view)
assert result == expected
27 changes: 27 additions & 0 deletions rest_framework_json_api/django_filters/backends.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
import warnings

from django_filters import VERSION
from django_filters.rest_framework import DjangoFilterBackend
Expand Down Expand Up @@ -142,3 +143,29 @@ def filter_queryset(self, request, queryset, view):
return filter_class(kwargs['data'], queryset=queryset, request=request).qs

return queryset

def get_schema_operation_parameters(self, view):
"""
Return Open API query parameter schema.
"""
try:
# queryset = view.get_queryset()
queryset = view.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': 'filter[{}]'.format(field_name.replace('__', '.')),
'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()
]