How to use mixins, Viewsets & Routers to create a Todo API in Django Rest Framework

How to use mixins, Viewsets & Routers to create a Todo API in Django Rest Framework

We will learn to create an API using mixins, Viewsets & Routers.

·

3 min read

Introduction

Following this link: https://emmakodes.com/build-a-todo-api-backend-using-generic-class-based-views-in-django-rest-framework we implemented a Todo API using Generic class-based views in Django Rest Framework.

In this article, we will see how to use mixins, Viewsets & Routers to create the same Todo API.

Note: This article is a follow-up from https://emmakodes.com/build-a-todo-api-backend-using-generic-class-based-views-in-django-rest-framework

Using mixins

To use mixins:

  • Replace the code in the views.py file of the todo app directory with the following code:
from .models import Todo
from .serializers import TodoSerializer
from rest_framework import mixins
from rest_framework import generics

class TodoList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

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

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


class TodoDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

    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're building our view using GenericAPIView(which helps to provide the core functionality), and adding in ListModelMixin and CreateModelMixin to TodoList class to help process the listing and creation of new Todo objects.

We also added RetrieveModelMixin, UpdateModelMixin, and DestroyModelMixin to TodoDetail class to provide retrieve, update and destroy actions respectively for a single Todo object.

You can start your development server and see that your API is working as before.

Using Viewsets & Routers

REST framework includes an abstraction for dealing with ViewSets, that allows the developer to concentrate on modeling the state and interactions of the API, and leave the URL construction to be handled automatically, based on common conventions.

  • Replace the code in the views.py file of the todo app directory with the following code:
from rest_framework import viewsets
from .models import Todo
from .serializers import TodoSerializer

class TodoViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.

    """
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

This time we've used the ModelViewSet class in order to get the complete set of default read and write operations. We're still setting the query set and serializer_class attributes exactly as we did when we were using regular views, but we no longer need to provide the same information to two separate classes.

  • Replace the code in the urls.py file of the todo app directory with the following code:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'todos', views.TodoViewSet,basename="todo")

# The API URLs are now determined automatically by the router.
urlpatterns = [
    path('', include(router.urls)),
]

Because we're using ViewSet classes rather than View classes, we actually don't need to design the URL conf ourselves. The conventions for wiring up resources into views and URLs can be handled automatically, using a Router class. All we need to do is register the appropriate view sets with a router, and let it do the rest.

Start your development server and go to the following address on your web address to see the API in action: http://127.0.0.1:8000/api/todos/ http://127.0.0.1:8000/api/todos/1/

Using viewsets can be a really useful abstraction. It helps ensure that URL conventions will be consistent across your API, minimizes the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf.

Conclusion

The end. Thanks for reading.

Check out how to build the same Todo API backend using Generic class-based views in Django Rest Framework: https://emmakodes.com/build-a-todo-api-backend-using-generic-class-based-views-in-django-rest-framework