Bulk Create With Django REST Framework
In this quick post I will go over how to create an endpoint that allows bulk creation of a resource using Django REST Framework.
The Serializer
Let's assume that we will be working with an existing Book
model in our Django application. We will create a serializer for this model using Django REST's ModelSerializer helper class:
# serializers.py
from myapp.models import Book
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
The "__all__"
string indicates that we want to serialize all of the model's fields.
The View
Before creating the view, we will first need to create a mixin that will allow the view to handle an array of JSON objects in the request so that the actual view can process and create new objects in a bulk fashion:
class CreateListMixin:
"""Allows bulk creation of a resource."""
def get_serializer(self, *args, **kwargs):
if isinstance(kwargs.get('data', {}), list):
kwargs['many'] = True
return super().get_serializer(*args, **kwargs)
This mixin overwrites the get_serializer
method and makes it check if the incoming body is a list. If it is, it proceeds to assign a boolean value for the many
key in the kwargs.
=> Adding the CreateList
prefix to the mixin class name is a good naming practice that quickly allows us to know that this is a mixin for bulk creation. Additionally, you will probably want to place this mixin in its own module (i.e views/mixins/rest.py
)
We can now create this view and make it use the mixin. We will make use of Django REST's ModelViewSet to simplyify things:
from rest_framework import viewsets
from myapp.serializers import BoookSerializer
from myapp.views.mixins.rest import CreateListMixin
from myapp.models import Book
class BookViewSet(CreateListMixin, viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
Setting the URL
Lastly we need to set a URL to make the request to. We can use a Django REST router to easily set this endpoint up:
# urls.py
from django.conf.urls import url, include
from rest_framework import routers
from views import BookViewSet
router = routers.DefaultRouter()
router.register(r'books', BookViewSet)
And that's pretty much it!