36. Class-based views in the Django REST framework

We’ve already seen that provides the means of writing either function-based or class-based views.

The class based views gave us the opportunity to write much more streamlined code. And the Django REST Framework provides much the same abilities.

So instead of using Python functions with the various decorators, and simulating switch case statements, we can instead just use the REST framework class-based views.

The REST framework provides three ways of handling class-based views. The simplest uses the Rest framework APIView, and requires that we write our GET, POST, PUT, DELETE functions. And that’s much like the function based views that we’ve already seen.

Or if we want to customise the approach, we can use a mixins approach where we can tailor which of our views responds to which HTTP methods.

So let’s scroll up to the top of api.py, and we’re going to import a couple of packages:

from rest_framework import generics
from rest_framework import mixins

Let’s scroll down and change the Genes List view. So we can add this code at the bottom:

class GeneList(generics.ListAPIView):
    queryset = Gene.objects.all()
    serializer_class = GeneListSerializer

This will function like the code we previously wrote:

@api_view(['GET'])
def genes_list(request):
    if request.method == 'GET':
        gene = Gene.objects.all()
        serializer = GeneListSerializer(gene, many=True)
        return Response(serializer.data)

Of course we now have to jump back to urls.py and correct the view:

path('api/genes/', api.GeneList.as_view()),

Now we can turn our attention to the gene_detail function in api.py. We can comment out or remove the old function, and use a new function.

We want this to be able to create, restore, update and destroy, so we can inherit these functionalities from the mixins. We also inherit from the main generics class to give generic operations.

We need to define a queryset, and a serializer_class. Then we have to implement each of the functions that we want.

class GeneDetail(mixins.CreateModelMixin,
                 mixins.RetrieveModelMixin,
                 mixins.UpdateModelMixin,
                 mixins.DestroyModelMixin,
                 generics.GenericAPIView):
    queryset = Gene.objects.all()
    serializer_class = GeneSerializer

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

We need to change the path once again in urlpatterns in urls.py too:

path('api/gene/<int:pk>/', api.GeneDetails.as_view()),

This will now show the two API views – individual genes in GeneDetail and the whole list in GeneList – as it did before.

Wednesday 24 November 2021, 12 views


Leave a Reply

Your email address will not be published. Required fields are marked *