OpenApi documentation missing filtersets on custom actions
CelestialGuru opened this issue · comments
Adding filtersets to my viewset works when tested, but the generated OpenApi documenation is absent any details of the query parameters.
class RunLayoutNodeFilterSet(filterset.FilterSet):
class Meta:
model = models.LayoutNode
fields = ("run",)
id__in = NumberInFilter(field_name="id", lookup_expr="in")
class RunLayoutNodeViewSet(viewsets.ModelViewSet):
...
filter_backends = (DjangoFilterBackend,)
filterset_class = filtersets.RunLayoutNodeFilterSet
@decorators.action(detail=False, methods=["delete"], url_path="bulk-destroy")
def bulk_destroy(self, request, *args, **kwargs):
"""Delete items in bulk"""
queryset = self.get_queryset()
filtered = self.filter_queryset(queryset)
if not self.allow_bulk_destroy(queryset, filtered):
return Response(status=status.HTTP_400_BAD_REQUEST)
else:
self.perform_bulk_destroy(filtered)
return Response(status=status.HTTP_204_NO_CONTENT)
def allow_bulk_destroy(self, queryset, filtered):
"""
Hook to ensure that the bulk destroy should be allowed.
By default this checks that the destroy is only applied to filtered querysets.
"""
return self.request.GET
def perform_bulk_destroy(self, instances):
for instance in instances:
self.perform_destroy(instance)
If I curl localhost:8000/api/quote/run-layout-nodes/bulk-destroy
I correctly get a 400 status code. If I curl localhost:8000/api/quote/run-layout-nodes/bulk-destroy?id__in=1
, that works too.
If I go to localhost:8000/schema/swagger-ui/
, and look at the documenation for the endpoint, there's nothing about filters. The regular list-view has the filters, just not this custom action.
I've tried changing the method to others like GET or whatever, still no luck.
Usually django-filters only make sense on endpoints that return or operate on a list. For viewsets, that is usually only thelist()
method. To signal the "list" nature of your custom action, you need to provide that information via decorator:
@extend_schema(filters=True)
@decorators.action(detail=False, methods=["delete"], url_path="bulk-destroy")
def bulk_destroy(self, request, *args, **kwargs):
...
As per #1432 the in-built schema support is going to be deprecated in the next version.
Rather, I recommend you migrate to use drf-spectacular
, which is much more fully featured, and under active development.
https://drf-spectacular.readthedocs.io/en/latest/readme.html
If for some reason you're not able to use drf-spectacular
you can copy the django_filters.rest_framework.backends.DjangoFilterBackend
into your own project to customise as needed. (But use drf-spectacular
.)
Thanks.