How do I create multiple model instances with Django Rest Framework?

django rest framework one to one serializer
django rest framework update multiple objects
django rest framework serializer multiple models
django rest framework nested serializer post
django rest framework forms
get_serializer_class
django rest framework related fields
get_serializer_context

I would like to save and update multiple instances using the Django Rest Framework with one API call. For example, let's say I have a "Classroom" model that can have multiple "Teachers". If I wanted to create multiple teachers and later update all of their classroom numbers how would I do that? Do I have to make an API call for each teacher?

I know currently we can't save nested models, but I would like to know if we can save it at the teacher level. Thanks!

I know this was asked a while ago now but I found it whilst trying to figure this out myself.

It turns out if you pass many=True when instantiating the serializer class for a model, it can then accept multiple objects.

This is mentioned here in the django rest framework docs

For my case, my view looked like this:

class ThingViewSet(viewsets.ModelViewSet):
    """This view provides list, detail, create, retrieve, update
    and destroy actions for Things."""
    model = Thing
    serializer_class = ThingSerializer

I didn't really want to go writing a load of boilerplate just to have direct control over the instantiation of the serializer and pass many=True, so in my serializer class I override the __init__ instead:

class ThingSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        many = kwargs.pop('many', True)
        super(ThingSerializer, self).__init__(many=many, *args, **kwargs)

    class Meta:
        model = Thing
        fields = ('loads', 'of', 'fields', )

Posting data to the list URL for this view in the format:

[
    {'loads':'foo','of':'bar','fields':'buzz'},
    {'loads':'fizz','of':'bazz','fields':'errrrm'}
]

Created two resources with those details. Which was nice.

I have no problem adding/updating a single instance of one of my models in Django, but how can I set up a view that will allow me to add multiple instances at​  I want to create multiple objects in one POST request. I've already read answers to similar questions but didn't find acceptible solution for my problem. Here's what I'm trying to do: request: r

I came to a similar conclusion as Daniel Albarral, but here's a more succinct solution:

class CreateListModelMixin(object):

    def get_serializer(self, *args, **kwargs):
        """ if an array is passed, set serializer to many """
        if isinstance(kwargs.get('data', {}), list):
            kwargs['many'] = True
        return super(CreateListModelMixin, self).get_serializer(*args, **kwargs)

I am using Django as the backend server and Vue.js for the front end Movie app. I have a Ticket model class MovieTicket(models.Model): show  I would like to save and update multiple instances using the Django Rest Framework with one API call. For example, let's say I have a "Classroom" model that can have multiple "Teachers". If I wanted to create multiple teachers and later update all of their classroom numbers how would I do that?

Here's another solution, you don't need to override your serializers __init__ method. Just override your view's (ModelViewSet) 'create' method. Notice many=isinstance(request.data,list). Here many=True when you send an array of objects to create, and False when you send just the one. This way, you can save both an item and a list!

from rest_framework import status, viewsets
from rest_framework.response import Response

class ThingViewSet(viewsets.ModelViewSet):

"""This view snippet provides both list and item create functionality."""

    #I took the liberty to change the model to queryset
    queryset = Thing.objects.all()
    serializer_class = ThingSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, many=isinstance(request.data,list))
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

Django Rest Framework, created by Tom… to serializers, which act as translators between Django model instances and their representations such as json . Handling multiple creates/updates/deletes in nested serializers. Django REST Framework is a wrapper over default Django Framework, basically used to create APIs of various kinds. There are three stages before creating a API through REST framework, Converting a Model’s data to JSON/XML format (Serialization), Rendering this data to the view, Creating a URL for mapping to the viewset.

I couldn't quite figure out getting the request.DATA to convert from a dictionary to an array - which was a limit on my ability to Tom Manterfield's solution to work. Here is my solution:

class ThingSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        many = kwargs.pop('many', True)
        super(ThingSerializer, self).__init__(many=many, *args, **kwargs)

    class Meta:
        model = Thing
        fields = ('loads', 'of', 'fields', )

class ThingViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet ):
    queryset = myModels\
        .Thing\
        .objects\
        .all()
    serializer_class = ThingSerializer

    def create(self, request, *args, **kwargs):
        self.user = request.user
        listOfThings = request.DATA['things']

        serializer = self.get_serializer(data=listOfThings, files=request.FILES, many=True)
        if serializer.is_valid():
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

And then I run the equivalent of this on the client:

var things = {    
    "things":[
        {'loads':'foo','of':'bar','fields':'buzz'},
        {'loads':'fizz','of':'bazz','fields':'errrrm'}]
}
thingClientResource.post(things)

Django REST Framework (DRF) is a terrific tool for creating very flexible REST APIs. qs = self.meals.through.objects.all().aggregate(total_price=models. However, DRF is not so friendly when you need to have multiple  Celery is a great tool which can help your Django project to do background tasks. And it can also improve the performance of Django project. But it seems there is no good tutorial series to talk about how to make Celery work with Django. So I decide to do it in the next weeks. This is the first one. After you read it, you will learn

I think the best aprouch to respect the propoused architecture of the framework will be to create a mixin like this:

class CreateListModelMixin(object):

    def create(self, request, *args, **kwargs):
        """
            Create a list of model instances if a list is provides or a
            single model instance otherwise.
        """
        data = request.data
        if isinstance(data, list):
            serializer = self.get_serializer(data=request.data, many=True)
        else:
            serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED,
                    headers=headers)

Then you can override the CreateModelMixin of ModelViewSet like this:

class <MyModel>ViewSet(CreateListModelMixin, viewsets.ModelViewSet):
    ...
    ...

Now in the client you can work like this:

var things = [    
    {'loads':'foo','of':'bar','fields':'buzz'},
    {'loads':'fizz','of':'bazz','fields':'errrrm'}
]
thingClientResource.post(things)

or

var thing = {
    'loads':'foo','of':'bar','fields':'buzz'
}

thingClientResource.post(thing)

EDIT:

As Roger Collins suggest in her response is more clever to overwrite the get_serializer method than the 'create'.

View (and mixin) for serializing multiple models or querysets in Django Rest Framework Build Status Coverage Status PyPI version. Multiple Model View. Django Rest Framework provides some incredible tools for serializing data, but  A Serializer transforms model instances into JSON. This the real "magic" that Django Rest Framework provides for us. Consider that the end result of a traditional website is a page of HTML, CSS, and content from the database.

Django REST generic views are amazing, but working with request.data in GenericAPIView): """ Concrete view for creating a model instance. Comment créer plusieurs instances de model avec Django Rest Framework? j'aimerais enregistrer et mettre à jour plusieurs instances en utilisant le reste du Framework Django avec un appel API. Par exemple, disons que j'ai un modèle de "salle de classe" qui peut avoir plusieurs "enseignants".

Serialization is the process of translating data structures into a format that can be stored, which in this case means turning querysets and model instances into native Python datatypes and then into JSON. Deserialization is the opposite, taking JSON and turning it into native Python datatypes and then into model instances. Serializers are not magic.

Then I tried to use this answer to create multiple model instances at once. The problem is it also creates the same Product twice instead of using the newly created Product Id to insert the next ProductDescription .

Comments
  • Here is similar question with solution that worked for me: stackoverflow.com/questions/21439672/…
  • Ha, that's a good catch. I've updated my code to actually do something with the now defaulted many value. It was a typing error on my part. Turns out just sending the data in the format shown does the job via the deprecated method though. Warning, changes are untested.
  • What does request.DATA look like in this case? It can't be a dictionary - or do they stick it in the dict somehow?
  • @akaphenom I don't know if you found your answer but it seems that request.DATA can be either a list containing a dict or a dict containing a list containing a dict depending on how you serialize it. At least that's been my experience.
  • its good to know. I have moved on from django work,so I haven't focused. But I ma happy to have this answer a little more complete.
  • doesn't work for me { "non_field_errors": [ "Invalid data. Expected a dictionary, but got list." ] }
  • This made my day! I confirm this works fine and accepts both lists and dict.
  • How is this expected to work given request.data is a QueryDict and not a dict or list? It works in unit tests but not in actual runtime due to that fact (for me, at least).
  • kwargs.get('data', {}) will return a QueryDict, and thus fail the ininstance, so many will not be set to True.
  • @RogerCollins If one of the list items raises validation error, entire request fails. Is there a way to skip invalid items and create rest of the instances?