TLT: Retrieving A Random Database Object Using Django Rest Framework Viewsets

I wanted to create a random object retrieval endpoint for my REST API. One of the interesting applications I'm working on requires a 'Get Random' button, which interacts with my server via that endpoint.

Problem

I have a number of database objects. I'm constructing a view using the DRF's ModelViewset. When the user goes to .../api/books/0/, instead of my application encountering an error JSON object, it'll be provided a random object from my database in JSON format. I can use this in my AJAX request behind my 'Get Random' button.

Solution

My model:

class Book(models.Model):  
    title = models.CharField(max_length=255)

My DRF serializer:

class BookSerializer(serializers.ModelSerializer):  
    title = serializers.CharField()

    class Meta:
        model = Book
        fields = ('title', )

In my view, books/views.py:

class BookAPIView(viewsets.ModelViewSet):  
    queryset = Book.objects.all()
    model = Book
    serializer_class = BookSerializer

    def retrieve(self, request, pk=None):
        if pk == '0':
            book = Book.objects.order_by('?').first()
            serializer = BookSerializer(book)
            return Response(serializer.data)
        else:
            return super(BookAPIView, self).retrieve(request, pk)

What we're doing is overriding the retrieve() method in ModelViewSet so that it checks the primary key specified in the URL. If the primary key specified is 0, the queryset becomes only the first database object in a random-ordered query result. first() is used instead of [0] as a convenience instead of writing out the entire exception handler. Check the docs for details. In the case that the primary key specified is anything but 0, the retrieve method will act appropriately (as it was originally intended).

Greg

Software Engineer

Subscribe to GregBlogs