Home > Enterprise >  django-filters filter by Boolean field with DRF
django-filters filter by Boolean field with DRF

Time:12-30

I'm following the tutorial here: https://www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend (specifically the django-filter-backend section)

and I am unable to get this to work. My goal is to retrieve a list of "containers" that have the "in_use" field set to True, but it keeps returning all the records in the table. I can't really see what I am missing. I have added django-filters to my installed apps list and also added this to my REST_FRAMEWORK block: 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']

This is the API endpoint I'm trying to hit in postman: http://127.0.0.1:8000/displaydata/containers?in_use=True I've tried passing both 'True' and 'true', as well as 0s and 1s.

views.py

class ContainerViews(APIView):
    def get(self, request, id=None):
        if id:
            container = Container.objects.get(id=id)
            serializer = ContainerSerializer(container)
            return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
        else:
            containers = Container.objects.all()
            serializer = ContainerSerializer(containers, many=True)
            filter_backends = [DjangoFilterBackend]
            filterset_fields = ['in_use']
            return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)

CodePudding user response:

You need to pass queryset and filter_backends as class attributes like this

class ProductList(generics.ListAPIView):
    queryset = Container.objects.all()
    serializer_class = ContainerSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['in_use']

This View only serves 'list' requests (many models). If you want also serve 'get' requests (single model by ID) you need ReadOnlyModelViewSet

class ProductViewSet(ReadOnlyModelViewSet):
    queryset = Container.objects.all()
    serializer_class = ContainerSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['in_use']

You can use it in urls.py like this

router = DefaultRouter()
router.register("product", ProductViewSet)
urlpatterns = [
    path("", include(router.urls)),
    ...
]
  • Related