From 717bab5a90999b330e686d3bd976a3ce9c60f90d Mon Sep 17 00:00:00 2001 From: Mahmoud Barry Date: Sun, 3 Mar 2024 17:00:51 +0000 Subject: [PATCH] Add BulkCreateModelMixin to allow bulk creation of models. --- rest_framework/generics.py | 19 +++++++++++++++++++ rest_framework/mixins.py | 27 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 167303321..d7c57b1cf 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -190,6 +190,17 @@ class CreateAPIView(mixins.CreateModelMixin, """ Concrete view for creating a model instance. """ + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class BulkCreateAPIView(mixins.BulkCreateModelMixin, + GenericAPIView): + """ + Concrete view for creating a model instance. + """ + def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) @@ -199,6 +210,7 @@ class ListAPIView(mixins.ListModelMixin, """ Concrete view for listing a queryset. """ + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -208,6 +220,7 @@ class RetrieveAPIView(mixins.RetrieveModelMixin, """ Concrete view for retrieving a model instance. """ + def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) @@ -217,6 +230,7 @@ class DestroyAPIView(mixins.DestroyModelMixin, """ Concrete view for deleting a model instance. """ + def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) @@ -226,6 +240,7 @@ class UpdateAPIView(mixins.UpdateModelMixin, """ Concrete view for updating a model instance. """ + def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) @@ -239,6 +254,7 @@ class ListCreateAPIView(mixins.ListModelMixin, """ Concrete view for listing a queryset or creating a model instance. """ + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -252,6 +268,7 @@ class RetrieveUpdateAPIView(mixins.RetrieveModelMixin, """ Concrete view for retrieving, updating a model instance. """ + def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) @@ -268,6 +285,7 @@ class RetrieveDestroyAPIView(mixins.RetrieveModelMixin, """ Concrete view for retrieving or deleting a model instance. """ + def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) @@ -282,6 +300,7 @@ class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin, """ Concrete view for retrieving, updating or deleting a model instance. """ + def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 6ac6366c7..435a3d6f5 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -15,6 +15,7 @@ class CreateModelMixin: """ Create a model instance. """ + def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) @@ -32,10 +33,33 @@ class CreateModelMixin: return {} +class BulkCreateModelMixin: + """ + Bulk create model instances. + """ + + def create(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data, many=True) + serializer.is_valid(raise_exception=True) + self.perform_bulk_create(serializer) + headers = self.get_success_headers(serializer.data) + return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) + + def perform_bulk_create(self, serializer): + serializer.save() + + def get_success_headers(self, data): + try: + return {'Location': str(data[api_settings.URL_FIELD_NAME])} + except (TypeError, KeyError): + return {} + + class ListModelMixin: """ List a queryset. """ + def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) @@ -52,6 +76,7 @@ class RetrieveModelMixin: """ Retrieve a model instance. """ + def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) @@ -62,6 +87,7 @@ class UpdateModelMixin: """ Update a model instance. """ + def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() @@ -91,6 +117,7 @@ class DestroyModelMixin: """ Destroy a model instance. """ + def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance)