Routers and ViewSets in Django Rest Framework

In this Python tutorial, You will learn how to implement routers and viewsets in Django in Django Rest Framework to generate some common view logic and API endpoints automatically.

You will understand the routers and viewsets concept by building a small project based on the library system where users can create, remove, update, and view the authors, books, and reviews.

Additionally, you will understand “What are routers and viewsets?”, how to make any class viewset, and how to configure the routers for your viewset.

Routers and ViewSets in Django Rest Framework

In the Django Rest Framework, to auto config the URLs with ViewSets, Routers are used. Let’s see an example of a library management system where users can create, remove, update, and view the authors, books, and reviews:

Setting Up the Django Project

First, create a virtual environment by typing the following command in your terminal or command prompt.

python -m venv env

Activate the envrionment ‘env’.

env\Scripts\activate

Install the latest version of Django using the below command.

pip install Django

Also, install the Django Rest Framework package.

pip install djangorestframework

Create a new Django project named ‘router_viewset’ using the below command.

django-admin startproject router_viewset
Routers and ViewSets in Django Project Creation

Then change the directory to router_viewset.

cd router_viewset

Create a new app named ‘app_route_viewset’ using the below command.

django-admin startapp app_route_viewset
Routers and ViewSets in Django App Creation

Next, configure the setting.py for the apps, so add the newly created app ‘app_route_viewset’ and ‘rest_framework’ to the INSTALLED_APPS section of that file.

INSTALLED_APPS = [
    ....,
    'app_route_viewset',
    'rest_framework',
]
Setting Apps Routers and ViewSets in Django

Creating Models for Routers and ViewSets in Django

Now open the model.py file of your Django app ‘app_route_viewset’ and create or add three models Author, Book and Review by adding the following code.

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)
    bio = models.TextField()

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    summary = models.TextField()
    publication_date = models.DateField()

    def __str__(self):
        return self.title

class Review(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    review_text = models.TextField()
    reviewer_name = models.CharField(max_length=100)
    review_date = models.DateField(auto_now_add=True)

    def __str__(self):
        return f"Review for {self.book.title} by {self.reviewer_name}"
Routers and ViewSets in Django Creating Models

Add the models to the admin.py file of your Django app by adding the following code.

from django.contrib import admin
from .models import Author, Book, Review

# Register your models here.
admin.site.register(Author)
admin.site.register(Book)
admin.site.register(Review)
Registering Routers and ViewSets in Django

Run the below commands one by one in your terminal or command prompt to migrate the Django models.

python manage.py makemigrations
python manage.py migrate
Migrating Models for Routers and ViewSets in Django

Read How to Deploy AI Model with Django

Routers and ViewSets in Django Creating Serializers

Serializers in Django convert the Models into Python data types that can be rendered as JSON data in an easy way.

Create a new file called serializers.py in the Django app ‘app_route_viewset’ and create the three serializers file named AuthorSerializer, BookSerializer and ReviewSerializer by adding the following code.

from rest_framework import serializers
from .models import Author, Book, Review

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

class ReviewSerializer(serializers.ModelSerializer):
    class Meta:
        model = Review
        fields = '__all__'
Routers and ViewSets in Django Creating Serializers

In the above code, from line numbers 1 to 2, importing the module serializers from the Django Rest Framework and three models class Author, Book and Review from the file models.py in the current app directory.

Let’s understand from lines numbers 4 to 7, creating a serializer class named ‘AuthorSerializer’ and this class inherits the ModelSerializer provided by the Django Rest Framework.

  • The ModelSerializer automatically generates the serializer fields based on the specified field names in the Django Model.
  • Then class Meta: is used to provide the additional configuration, this is the general way to provide the additional configuration in Django. After this, model = Author means use the model Author for the serialization.
  • Then at line 7, fields = ‘__all__’ means use all the fields of the Django model ‘Author’ for the representation of the serialization. You can also serialize only the particular fields by providing field names in the brackets as fields = (‘name’, ‘bio’) instead of fields = ‘__all__’.

The same concept to the other two serializers BookSerializer and ReviewSerializer.

Defining Routers and ViewSets in Django

To implement the CRUD logic in Django, usually you create separate views for handling the HTTP method such as CreateView, ReadView, UpdatView and DeleteView and some of the logic of these views are the same like querying and retrieving the information from databases etc.

ViewSets in the Django Rest Framework allows us to define all the logic for the views in one class related to the HTTP methods.

Let’s define the ViewSets for the Author, Book and Review by adding the following code in the views.py file of your Django app.

from rest_framework import viewsets
from .models import Author, Book, Review
from .serializers import AuthorSerializer, BookSerializer, ReviewSerializer

class AuthorViewSet(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

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

class ReviewViewSet(viewsets.ModelViewSet):
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer
Routers and ViewSets in Django Defining ViewSets

In the above code from lines numbers 1 to 4, importing the module viewsets from the Django Rest Framework, models Author, Book, Review and serializer AuthorSerializer, BookSerializer, ReviewSerializer.

  • Then at line number 5, AuthorViewSet is defined which belongs to subclass viewsets.ModelViewSet.
  • The ModelViewSet class provides the CRUD functionality to the AuthorViewSet by default, so you don’t need to define the CRUD manually. It allows you to build API quickly without writing the CRUD methods.
  • After this in line 6, the queryset is an attribute that accepts the set of objects as queryset on which viewset operates and this set of objects or records is retrieved from the model (Author).

Finally, in line 7, the attribute serializer_class accepts the serializer class (AuthorSerializer) that you have defined in the serilizers.py file to convert the model queryset to JSON data and vice-versa. Basically, it tells viewset how to transform the queryset to the JSON representations.

Let’s see “What are the routers?”, Suppose you have defined the views for the CRUD operations, and to define URLs, you will also define the URLs and map them to each view separately in the file urls.py of your Django app or project.

  • Manually writing the URL pattern for each view is repetitive, especially in the case of CRUD operations.
  • So using the Routers provided by the Django Rest framework, you can generate the URL pattern automatically. This means you don’t need to define the URL pattern for each CRUD operation, routers will generate dynamically.

Create a new file urls.py in your Django app ‘app_route_viewset’ and define the routers by adding the following code in that file.

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import AuthorViewSet, BookViewSet, ReviewViewSet

router = DefaultRouter()
router.register(r'authors', AuthorViewSet)
router.register(r'books', BookViewSet)
router.register(r'reviews', ReviewViewSet)

urlpatterns = [
     path('', include(router.urls)),
]
Defining Routers and ViewSets in Django App URL

In the above code from line numbers 2 to 3, import the DefaultRouter from the Django Rest Framework and all the viewset AuthorViewSet, BookViewSet, and ReviewViewSet from the file views.py.

  • From 5 to 8, creating an instance of the DefaultRouter as router, this router generates the URL pattern automatically for the API endpoints based on the viewset.
  • Then registering the viewset AuthorViewSet, BookViewSet and ReviewViewSet with the router using the router.register() method.

The router.register() accepts two arguments, the first is the URL prefix and the second is the viewset. In the above code, router.register(r’authors’, AuthorViewSet) means registering the AuthorViewSet with URL prefix authors and the router will generate the following URL patterns.

URL PatternsMeaning
‘GET /authors/’To get all authors
‘GET /authors/<id>/’To get the single author by ID
‘POST /authors/’To create a new author

It also generates the same URL pattern for the other viewset BookViewSet and RevieViewSet.

URL PatternsMeaning
‘GET /books/’To get all books
‘GET /books/<id>/’To get the single book by ID
‘POST /books/’To create a new book
‘GET /reviews/’To get all reviews
‘GET /reviews/<id>/’To get the single review by ID
‘POST /reviews/’To get a single review by ID

I have shown only three types of URL patterns for each viewset, but also generate URL patterns for deleting and updating the author, book and review.

Also, configure the URL at the Django project level by adding the following code in the urls.py file.

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('app_route_viewset.urls')),
]
Defining Routers and ViewSets in Django Project Level URL

After defining the routers, run the below command in your terminal or command prompt to run the Django server.

python manage.py runserver

Then open your browser and type the URL http://127.0.0.1:8000/ and you see the page like this.

Defining Routers and ViewSets in Django

The above page shows the basic root view or the API endpoint for all the viewset related to the HTTP GET method. Let’s visit the API endpoint http://127.0.0.1:8000/authors/ and see.

Defining Routers and ViewSets in Django Author List

When you visit the URL http://127.0.0.1:8000/authors/, it fetches all the authors from the database and shows them here, but we haven’t added any author to the database so it is not showing any author and only showing an empty bracket [].

Let’s add the author by typing the author name in the Name field and description in the Bio field and then clicking on the POST button.

Adding Author Defining Routers and ViewSets in Django

Then again revisit the URL http://127.0.0.1:8000/authors/ and now you see the author that you have added.

Author Defining Routers and ViewSets in Django

Now add the multiple-author as you added in the above and access the author by passing the ID to the URL.

Suppose you want to retrieve the single author whose ID is 2, then type the URL http://127.0.0.1:8000/authors/2 as shown in the below picture.

Routers and ViewSets in Django Author By Id

As you can see in the above picture, you have retrieved the author details based on the author ID.

But if you look at the top, there is a DELETE button, Using this button you can delete the author and you can update the author detail by filling in the below form, and then clicking on the PUT button.

Let’s also add the book details written by the author, so visit the URL or API endpoint http://127.0.0.1:8000/books/ and specify the title, summary, publication date and author, then click on the POST button.

Routers and ViewSets in Django Adding Book

After adding the Book, again visit the URL http://127.0.0.1:8000/books/ and you see the list of books that you have added.

Routers and ViewSets in Django Viewing Book

In the above picture, you can see that the added book belongs to the author whose ID is 1 so in our case the author is Martin Gilbert. You can also view the specific book by passing the ID to the URL like this http://127.0.0.1:8000/books/1.

Now provide the review for the book, so visit the URL http://127.0.0.1:8000/reviews/ and type the review and reviewer name choose the book name, then click on the POST button.

Reviewing Book Routers and ViewSets in Django

Again revisit the URL http://127.0.0.1:8000/reviews/ and you see the review for the Book ‘The First World War’ which is represented by the book ID equal to 1.

Routers and ViewSets in Django Reviewing Book

You can also view the specific review by passing the review ID to the URL like this http://127.0.0.1:8000/reviews/1.

So you have successfully added the author, and book and given a review to a specific book using the API endpoints, this is how you can use the router and viewsets together to generate the CRUD logic and URL patterns for the viewset automatically.

Conclusion

In this Python tutorial, you have learned how to use the routers and views together to implement the CRUD logic and URL patterns for the views. By implementing the routers and viewsets, you built a project where users can perform the CRUD operation on authors, books, and reviews using the API endpoints. Basically, you created the API endpoints using the Django Rest Framework.

You may like to read: