Skip to content

Commit 4a70020

Browse files
committed
implement missing DjangoFilterBackend.get_schema_operation_parameters()
1 parent 7ad59e8 commit 4a70020

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

example/tests/unit/test_filter_schema_params.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import pytest
2-
from rest_framework import VERSION as DRFVERSION
31
from rest_framework import filters as drf_filters
42

53
from rest_framework_json_api import filters as dja_filters
@@ -13,17 +11,14 @@ class DummyEntryViewSet(EntryViewSet):
1311
backends.DjangoFilterBackend, drf_filters.SearchFilter)
1412
filterset_fields = {
1513
'id': ('exact',),
16-
'headline': ('exact',),
14+
'headline': ('exact', 'contains'),
15+
'blog__name': ('contains', ),
1716
}
1817

19-
def __init__(self):
18+
def __init__(self, **kwargs):
2019
# dummy up self.request since PreloadIncludesMixin expects it to be defined
2120
self.request = None
22-
23-
24-
# get_schema_operation_parameters is only available in DRF >= 3.10
25-
drf_version = tuple(int(x) for x in DRFVERSION.split('.'))
26-
pytestmark = pytest.mark.skipif(drf_version < (3, 10), reason="requires DRF 3.10 or higher")
21+
super(DummyEntryViewSet, self).__init__(**kwargs)
2722

2823

2924
def test_filters_get_schema_params():
@@ -41,7 +36,15 @@ def test_filters_get_schema_params():
4136
{
4237
'name': 'filter[headline]', 'required': False, 'in': 'query',
4338
'description': 'headline', 'schema': {'type': 'string'}
44-
}
39+
},
40+
{
41+
'name': 'filter[headline.contains]', 'required': False, 'in': 'query',
42+
'description': 'headline__contains', 'schema': {'type': 'string'}
43+
},
44+
{
45+
'name': 'filter[blog.name.contains]', 'required': False, 'in': 'query',
46+
'description': 'blog__name__contains', 'schema': {'type': 'string'}
47+
},
4548
]),
4649
(dja_filters.OrderingFilter, [
4750
{
@@ -65,12 +68,10 @@ def test_filters_get_schema_params():
6568
result = f.get_schema_operation_parameters(view)
6669
assert len(result) == len(expected)
6770
if len(result) == 0:
68-
return
71+
continue
6972
# py35: the result list/dict ordering isn't guaranteed
7073
for res_item in result:
7174
assert 'name' in res_item
7275
for exp_item in expected:
7376
if res_item['name'] == exp_item['name']:
7477
assert res_item == exp_item
75-
return
76-
assert False

rest_framework_json_api/django_filters/backends.py

+15
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,18 @@ def get_filterset_kwargs(self, request, queryset, view):
122122
'request': request,
123123
'filter_keys': filter_keys,
124124
}
125+
126+
def get_schema_operation_parameters(self, view):
127+
"""
128+
Convert backend filter `name` to JSON:API-style `filter[name]`.
129+
For filters that are relationship paths, rewrite ORM-style `__` to our preferred `.`.
130+
For example: `blog__name__contains` becomes `filter[blog.name.contains]`.
131+
132+
This is basically the reverse of `get_filterset_kwargs` above.
133+
"""
134+
result = []
135+
for res in super(DjangoFilterBackend, self).get_schema_operation_parameters(view):
136+
if 'name' in res:
137+
res['name'] = 'filter[{}]'.format(res['name']).replace('__', '.')
138+
result.append(res)
139+
return result

0 commit comments

Comments
 (0)