title: Django Rest Framework: How to bulk_create nested objects during de-serialization?
body: <p>I have three models:</p>
  <pre><code>class Customer(models.Model):
      name = models.CharField(max_length=30)
  
  class Order(models.Model):
      customer = models.ForeignKey(Customer,on_delete=models.CASCADE)
  
  class LineItem(models.Model):
      order = models.ForeignKey(Order,on_delete=models.CASCADE)
      name = models.CharField(max_length=30)
  </code></pre>
  <p>Here is my test:</p>
  <pre><code>class CreateOrdersTest(APITestCase):
      def setUp(self):
          self.TEST_SIZE = 10
          self.factory = APIRequestFactory()
          self._setup_source()
          self.data = self._build_data()
  
      def _setup_source(self):
          Customer.objects.create(name='test-customer')
  
      def _build_data(self):
          return [{'customer':'test-customer','lineitems':[{'name':'apples'},{'name':'oranges'}]} for x in range(self.TEST_SIZE)]
  
      def test_post_orders(self):
  
          request = self.factory.post('/create_orders',self.data)
          response = create_orders(request)
          response.render()
          self.assertEqual(response.status_code,status.HTTP_201_CREATED)
  </code></pre>
  <p>so the post object looks like</p>
  <pre><code>[{'customer': 'test-customer', 'lineitems': [{'name': 'apples'}, {'name': 'oranges'}]}, .... ] 
  </code></pre>
  <p>here are the serializers:</p>
  <pre><code>class BulkLineItemSerializer(serializers.ModelSerializer):
      def create(self,validated_data):
          lineitems = [LineItem(**validated_data) for item in validated_data]
          return LineItem.objects.bulk_create(**validated_data)
  
  class LineItemSerializer(serializers.ModelSerializer):
  
      order = ModelObjectidField()
  
      def create(self,validated_data):
          return LineItem.objects.create(**validated_data)
  
      class Meta:
          model = LineItem
          list_serializer_class = BulkLineItemSerializer
          fields = ['name','order']
  
  class BulkOrderSerializer(serializers.ListSerializer):
      def create(self,validated_data):
          orders = [Order(**item) for item in validated_data]
          return Order.objects.bulk_create(orders)
  
  class OrderSerializer(serializers.ModelSerializer):
  
      customer = serializers.SlugRelatedField(slug_field='name',queryset=Customer.objects.all())
  
      def create(self,validated_data):
          return Order.objects.create(**validated_data)
      
      class Meta:
          model = Order
          fields = ['customer']
          list_serializer_class = BulkOrderSerializer
  </code></pre>
  <p>then here is that ModelObjectidField I use for the order object.</p>
  <pre><code>class ModelObjectidField(serializers.Field):
  
      def to_representation(self, value):
          return value.id
  
      def to_internal_value(self, data):
          return data
  </code></pre>
  <p>Because I am passing the actual object into the field like &lt;Order(1)&gt;, I just return it directly for the internal_value.</p>
  <p>And finally here is my view. This is how I match the lineitems to the orders.</p>
  <pre><code>@api_view(['POST'])
  def create_orders(request):
      if request.method == 'POST':
          fixed_orders = []
          lineitems_matching = []
          offset = 0
          lineitems_data = []
          for order in request.data:
              order_lineitems = order['lineitems']
              lineitems_data.extend(order_lineitems)
              for item in order_lineitems:
                  lineitems_matching.append(offset)
              offset += 1
              fixed_orders.append(order)
          orderSerializer = OrderSerializer(data=fixed_orders,many=True)
          if orderSerializer.is_valid():
              orders = orderSerializer.save()
              fixed_lineitems = []
              offset = 0
              for lineitem_data in lineitems_data:
                  lineitem_data['order'] = orders[lineitems_matching[offset]]
                  fixed_lineitems.append(lineitem_data)
                  offset += 1
              lineItemSerializer = LineItemSerializer(data=fixed_lineitems, many=True) # this line is getting the error
              if lineItemSerializer.is_valid():
                  lineItemSerializer.save()
                  return Response(orderSerializer.data,status=status.HTTP_201_CREATED)
              return Response(lineItemSerializer.errors,status=status.HTTP_400_BAD_REQUEST)
          return Response(orderSerializer.errors,status=status.HTTP_400_BAD_REQUEST)
  </code></pre>
  <p>Currently I am getting this error:</p>
  <pre><code>(venv) alexmarshall@Alexs-MacBook-Pro spicy % ./manage.py test NestedOrderTest
  Creating test database for alias 'default'...
  System check identified no issues (0 silenced).
  E
  ======================================================================
  ERROR: test_post_orders (NestedOrderTest.tests.CreateOrdersTest)
  ----------------------------------------------------------------------
  Traceback (most recent call last):
    File &quot;/Users/alexmarshall/src/GreenData/spicy/spicy/NestedOrderTest/tests.py&quot;, line 23, in test_post_orders
      response = create_orders(request)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py&quot;, line 54, in wrapped_view
      return view_func(*args, **kwargs)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/django/views/generic/base.py&quot;, line 70, in view
      return self.dispatch(request, *args, **kwargs)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/views.py&quot;, line 509, in dispatch
      response = self.handle_exception(exc)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/views.py&quot;, line 469, in handle_exception
      self.raise_uncaught_exception(exc)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/views.py&quot;, line 480, in raise_uncaught_exception
      raise exc
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/views.py&quot;, line 506, in dispatch
      response = handler(request, *args, **kwargs)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/decorators.py&quot;, line 50, in handler
      return func(*args, **kwargs)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/spicy/NestedOrderTest/views.py&quot;, line 31, in create_orders
      lineItemSerializer = LineItemSerializer(data=fixed_lineitems, many=True)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/serializers.py&quot;, line 121, in __new__
      return cls.many_init(*args, **kwargs)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/serializers.py&quot;, line 158, in many_init
      return list_serializer_class(*args, **list_kwargs)
    File &quot;/Users/alexmarshall/src/GreenData/spicy/venv/lib/python3.8/site-packages/rest_framework/serializers.py&quot;, line 115, in __init__
      super().__init__(**kwargs)
  TypeError: __init__() got an unexpected keyword argument 'child'
  
  ----------------------------------------------------------------------
  Ran 1 test in 0.010s
  
  FAILED (errors=1)
  </code></pre>
  <p>I think the problem is that I am passing the lineitem serializer data that has the order itself. Here is what the fixed_lineitems data looks like:</p>
  <pre><code>[{'name': 'apples', 'order': &lt;Order: Order object (1)&gt;}, ... ]  
  </code></pre>
  <p>Thats what I am using the custom field for, but It doesn't seem to like it? I don't really know what that TypeError means. Why would it be getting a child? But really Im just not sure how to setup the serializers in this case. Any help?</p>
  <p>Edit: I changed the lineitem serializer to this and I believe its working!</p>
  <pre><code>class BulkLineItemSerializer(serializers.ListSerializer):
      def create(self,validated_data):
          lineitems = [LineItem(**item) for item in validated_data]
          return LineItem.objects.bulk_create(lineitems)
  </code></pre>