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.
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.
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,
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
 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).