diff --git a/rest_framework/schemas/inspectors.py b/rest_framework/schemas/inspectors.py index bdd720938..30f639f5b 100644 --- a/rest_framework/schemas/inspectors.py +++ b/rest_framework/schemas/inspectors.py @@ -337,18 +337,33 @@ class AutoSchema(ViewInspector): paginator = view.pagination_class() return paginator.get_schema_fields(view) + def _allows_filters(self, path, method): + """ + Determine whether to include filter Fields in schema. + + Default implementation looks for ModelViewSet or GenericAPIView + actions/methods that cause filtering on the default implementation. + + Override to adjust behaviour for your view. + + Note: Introduced in v3.7: Initially "private" (i.e. with leading underscore) + to allow changes based on user experience. + """ + if getattr(self.view, 'filter_backends', None) is None: + return False + + if hasattr(self.view, 'action'): + return self.view.action in ["list", "retrieve", "update", "partial_update", "destroy"] + + return method.lower in ["get", "put", "patch", "delete"] + def get_filter_fields(self, path, method): - view = self.view - - if not is_list_view(path, method, view): - return [] - - if not getattr(view, 'filter_backends', None): + if not self._allows_filters(path, method): return [] fields = [] - for filter_backend in view.filter_backends: - fields += filter_backend().get_schema_fields(view) + for filter_backend in self.view.filter_backends: + fields += filter_backend().get_schema_fields(self.view) return fields def get_encoding(self, path, method): diff --git a/tests/test_schemas.py b/tests/test_schemas.py index 184401a86..07c49b71d 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -139,7 +139,8 @@ class TestRouterGeneratedSchema(TestCase): url='/example/{id}/', action='get', fields=[ - coreapi.Field('id', required=True, location='path', schema=coreschema.String()) + coreapi.Field('id', required=True, location='path', schema=coreschema.String()), + coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.')) ] ) } @@ -179,7 +180,8 @@ class TestRouterGeneratedSchema(TestCase): url='/example/{id}/', action='get', fields=[ - coreapi.Field('id', required=True, location='path', schema=coreschema.String()) + coreapi.Field('id', required=True, location='path', schema=coreschema.String()), + coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.')) ] ), 'custom_action': coreapi.Link( @@ -225,7 +227,8 @@ class TestRouterGeneratedSchema(TestCase): fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field('a', required=True, location='form', schema=coreschema.String(title='A', description=('A field description'))), - coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')) + coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')), + coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.')) ] ), 'partial_update': coreapi.Link( @@ -235,14 +238,16 @@ class TestRouterGeneratedSchema(TestCase): fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field('a', required=False, location='form', schema=coreschema.String(title='A', description='A field description')), - coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')) + coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')), + coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.')) ] ), 'delete': coreapi.Link( url='/example/{id}/', action='delete', fields=[ - coreapi.Field('id', required=True, location='path', schema=coreschema.String()) + coreapi.Field('id', required=True, location='path', schema=coreschema.String()), + coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.')) ] ) } @@ -450,7 +455,8 @@ class TestSchemaGeneratorWithMethodLimitedViewSets(TestCase): url='/example1/{id}/', action='get', fields=[ - coreapi.Field('id', required=True, location='path', schema=coreschema.String()) + coreapi.Field('id', required=True, location='path', schema=coreschema.String()), + coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.')) ] ) }