Skip to content

Commit b1c6ea1

Browse files
author
Carlton Gibson
authored
Adjust schema get_filter_fields rules to match framework (#5454)
Closes #5237 Generics/ModelViewset performs filtering on: list, retrieve, put, patch and destroy (plus method equivalents). i.e. on list plus anything that calls `get_object`. This PR makes schema generation follow that. It adds `AutoSchema._allows_filters()` which can be overridden in subclasses. I’ve made this initially “private” so we can make quick changes if needs be in a 3.7.1 etc.
1 parent ab7e5c4 commit b1c6ea1

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

rest_framework/schemas/inspectors.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,18 +337,33 @@ def get_pagination_fields(self, path, method):
337337
paginator = view.pagination_class()
338338
return paginator.get_schema_fields(view)
339339

340-
def get_filter_fields(self, path, method):
341-
view = self.view
340+
def _allows_filters(self, path, method):
341+
"""
342+
Determine whether to include filter Fields in schema.
342343
343-
if not is_list_view(path, method, view):
344-
return []
344+
Default implementation looks for ModelViewSet or GenericAPIView
345+
actions/methods that cause filtering on the default implementation.
346+
347+
Override to adjust behaviour for your view.
345348
346-
if not getattr(view, 'filter_backends', None):
349+
Note: Introduced in v3.7: Initially "private" (i.e. with leading underscore)
350+
to allow changes based on user experience.
351+
"""
352+
if getattr(self.view, 'filter_backends', None) is None:
353+
return False
354+
355+
if hasattr(self.view, 'action'):
356+
return self.view.action in ["list", "retrieve", "update", "partial_update", "destroy"]
357+
358+
return method.lower in ["get", "put", "patch", "delete"]
359+
360+
def get_filter_fields(self, path, method):
361+
if not self._allows_filters(path, method):
347362
return []
348363

349364
fields = []
350-
for filter_backend in view.filter_backends:
351-
fields += filter_backend().get_schema_fields(view)
365+
for filter_backend in self.view.filter_backends:
366+
fields += filter_backend().get_schema_fields(self.view)
352367
return fields
353368

354369
def get_encoding(self, path, method):

tests/test_schemas.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ def test_anonymous_request(self):
139139
url='/example/{id}/',
140140
action='get',
141141
fields=[
142-
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
142+
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
143+
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
143144
]
144145
)
145146
}
@@ -179,7 +180,8 @@ def test_authenticated_request(self):
179180
url='/example/{id}/',
180181
action='get',
181182
fields=[
182-
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
183+
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
184+
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
183185
]
184186
),
185187
'custom_action': coreapi.Link(
@@ -225,7 +227,8 @@ def test_authenticated_request(self):
225227
fields=[
226228
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
227229
coreapi.Field('a', required=True, location='form', schema=coreschema.String(title='A', description=('A field description'))),
228-
coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B'))
230+
coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')),
231+
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
229232
]
230233
),
231234
'partial_update': coreapi.Link(
@@ -235,14 +238,16 @@ def test_authenticated_request(self):
235238
fields=[
236239
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
237240
coreapi.Field('a', required=False, location='form', schema=coreschema.String(title='A', description='A field description')),
238-
coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B'))
241+
coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')),
242+
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
239243
]
240244
),
241245
'delete': coreapi.Link(
242246
url='/example/{id}/',
243247
action='delete',
244248
fields=[
245-
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
249+
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
250+
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
246251
]
247252
)
248253
}
@@ -450,7 +455,8 @@ def test_schema_for_regular_views(self):
450455
url='/example1/{id}/',
451456
action='get',
452457
fields=[
453-
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
458+
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
459+
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
454460
]
455461
)
456462
}

0 commit comments

Comments
 (0)