I have a viewset which needs to have both flexible ordering by parameter and filtering by parameter for a custom list() over-ride. I am able to get ordering to work as well as filtering on various parameters via django-filter, but I cannot get them both to function simultaneously.
Here is my simplified views.py code that works for ordering the results:
class AssetViewSet(viewsets.GenericViewSet, AssetPaginationMixin,):
queryset = Asset.objects.all()
pagination_class = AssetPagination
serializer_class = serializers.AssetSerializer
filter_backends = (OrderingFilter, )
ordering_fields = ('id', 'session_id')
filter_class = AssetFilterSet
def list(self, request):
assets = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(assets, many=True)
return Response(serializer.data)
And here is the code that works for filtering:
class AssetViewSet(viewsets.GenericViewSet, AssetPaginationMixin,):
queryset = Asset.objects.all()
pagination_class = AssetPagination
serializer_class = serializers.AssetSerializer
filter_backends = (OrderingFilter, )
ordering_fields = ('id', 'session_id')
filter_class = AssetFilterSet
def list(self, request):
assets = AssetFilterSet(request.query_params)
serializer = self.get_serializer(assets, many=True)
return Response(serializer.data)
And finally, my filters.py code:
class AssetFilterSet(django_filters.FilterSet):
project_id = django_filters.NumberFilter()
submitted = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool)
class Meta:
model = Asset
fields = ['project',
'submitted']
The only difference is the first line in list(). For some reason, it seems like the AssetFilterSet needs to be applied directly within list() in order to take effect and is otherwise bypassed if I use self.filter_queryset in list() despite being specified by filter_class = AssetFilterSet.
viewset.ListViewSetorviewset.ModelViewSetsince you are using a model, then you don't need to providelistsince it will be inherited.