Search code examples
djangodjango-rest-frameworkmixinsdjango-rest-viewsets

Django Rest Framework: Get singular object using the root API


I am trying to set up an API endpoint that returns a singular object.

Right now I have:

class ShoppingCartViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
    """
    API endpoint that allows users to be viewed or edited.
    """
    serializer_class = ShoppingCartSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get_paginated_response(self, data):
        return Response(data)

    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)

Which uses the ListModelMixin and a filter to return one item, becasue each user has 1 shopping cart.

The issue is the filter function returns a queryset, but I only want a single item.

I attempted to use the RetrieveModelMixin but that doesn't run on the endpoint that I want. Retrieve runs on .../api/shopping-cart/id but I want to retrieve on .../api/shopping-cart because the filtering is done via the person who is logged in.

Any solutions?


Solution

  • The way I ended up solving it was still using the ListModelMixin, as I needed to benefits of the viewset.

    I overwrote the list() method with:

    class ShoppingCartViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
        """
        API endpoint that allows users to be viewed or edited.
        """
        serializer_class = ShoppingCartSerializer
        # authentication_classes = (TokenAuthentication,)
        # permission_classes = (IsAuthenticated,)
    
        def get_paginated_response(self, data):
            return Response(data)
    
        def list(self, request, *args, **kwargs):
            instance = ShoppingCart.objects.get(user=self.request.user)
            serializer = self.get_serializer(instance)
            return Response(serializer.data)
    

    which returns me a singular item on the root url .../api/shopping-cart without having to pass parameters because it filters based on user.