Search code examples
djangodjango-rest-frameworkdjango-filter

Optimize getting the first record in a table using an API endpoint with Django REST Framework and/or Django-filter


I'm trying to retrieve the first record in a table using the endpoint below (please suggest if there's a more sensible URL convention).

http://127.0.0.1:8000/api/review/?first

The view I have works, but I'm hoping to refactor it because it smells.

class ReviewViewSet(ModelViewSet):
    filter_backends = (DjangoFilterBackend, OrderingFilter)
    serializer_class = ReviewSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        first = self.request.query_params.get('first')
        queryset = RecordReview.objects.all()

        if first is not None:
            id_list = queryset.values_list('id')
            first_item = id_list.order_by('id').first()
            first_id = first_item[0]
            queryset = queryset.filter(id=first_id)

        return queryset

When I attempted to filter the queryset directly, I got errors like:

TypeError: object of type 'RecordReview' has no len()


Solution

  • The error comes from this line :

    first_id = first_item[0]
    

    This is because first_item is already a RecordReview, as it was retrieved using first()

    You can simplify get_queryset as follows though :

    class ReviewViewSet(ModelViewSet):
        filter_backends = (DjangoFilterBackend, OrderingFilter)
        serializer_class = ReviewSerializer
        permission_classes = [permissions.IsAuthenticated]
    
        def get_queryset(self):
            first = self.request.query_params.get('first')
            queryset = RecordReview.objects.all()
    
            if first is not None:
                queryset = queryset.order_by('id')[:1]
    
            return queryset