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.
This commit is contained in:
Carlton Gibson 2017-09-27 09:13:10 +02:00 committed by GitHub
parent ab7e5c4551
commit b1c6ea1240
2 changed files with 35 additions and 14 deletions

View File

@ -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):

View File

@ -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.'))
]
)
}