4

I'm writing a REST API using Django Rest Framework and I would like that one of my routes accepts bulk adding on POST method, to create multiple objects. Others methods (GET, PUT, PATCH, DELETE) will still remain the same, accepting only one at a time.

What I have so far is below and it's currently working just fine for posting one at a time.

In my urls.py:

path('book', books.BookViewSet.as_view()),

books.py:

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

serializer.py:

class BookSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        # I assume this is the method to be overridden to get this

    class Meta:
        model = Book
        fields = ('id', 'name', 'author_id', 'page_number', 'active')
Luc
  • 393
  • 7
  • 19

1 Answers1

3

Serializer create method, unfortunatelly creates data object by object.You can override create method of ModelViewSet and after validation use bulk_create method.

def create(self, request, *args, **kwargs):
    many = True if isinstance(request.data, list) else False
    serializer = BookSerializer(data=request.data, many=many)
    serializer.is_valid(raise_exception=True)
    author = request.user # you can change here
    book_list = [Book(**data, author=author) for data in serializer.validated_data]
    Book.objects.bulk_create(book_list)
    return Response({}, status=status.HTTP_201_CREATED)
kamilyrb
  • 2,502
  • 3
  • 10
  • 25
  • 1
    Just be aware that `bulk_create` does not trigger signals (`pre_save`, `post_save`). Also, `data = serializer.is_valid(raise_exception=True)` will handle validation and add the correct error message w/ nesting. – Andrew May 20 '20 at 23:06
  • This seems like the best solution indeed, but what if on my serializer I need to create the object and the `author_id` is the user making the POST request? I know I can get the user in the create method of `ModelViewSet`, but how do I do this so that my serializer knows the user as well when creating the object? Thanks – Luc May 20 '20 at 23:59
  • you can pass your author to Book model in `Book(**data,author=...)` part. I updated answer – kamilyrb May 21 '20 at 00:44