From ed88385c0be8d334e36b7d2c70235d6c7371cde9 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Tue, 26 Sep 2017 12:29:18 +0200 Subject: [PATCH] Adjust schema get_filter_fields rules to match framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- rest_framework/schemas/inspectors.py | 29 +++++++++++++++++++++------- tests/test_schemas.py | 18 +++++++++++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/rest_framework/schemas/inspectors.py b/rest_framework/schemas/inspectors.py index bdd720938b..30f639f5ba 100644 --- a/rest_framework/schemas/inspectors.py +++ b/rest_framework/schemas/inspectors.py @@ -337,18 +337,33 @@ def get_pagination_fields(self, path, method): paginator = view.pagination_class() return paginator.get_schema_fields(view) - def get_filter_fields(self, path, method): - view = self.view + def _allows_filters(self, path, method): + """ + Determine whether to include filter Fields in schema. - if not is_list_view(path, method, view): - return [] + Default implementation looks for ModelViewSet or GenericAPIView + actions/methods that cause filtering on the default implementation. + + Override to adjust behaviour for your view. - if not getattr(view, 'filter_backends', None): + 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): + 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 184401a868..07c49b71d1 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -139,7 +139,8 @@ def test_anonymous_request(self): 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 @@ def test_authenticated_request(self): 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 @@ def test_authenticated_request(self): 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 @@ def test_authenticated_request(self): 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 @@ def test_schema_for_regular_views(self): 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.')) ] ) } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy