1

I am attempting to create many model instances in one POST using a Mixin to support POST of arrays.

My use case will involve creating 1000s of model instances in each call. This very quickly becomes slow with DRF due to each model being created one at a time.

In an attempt to optimise the creation, I have changed to use bulk_create(). While this does result in a significant improvement, I noticed that for each model instance being created, a SELECT statement was being run to get the ForeignKey, which I traced to the call to serializer.is_valid().

As such, adding n instances would result in n SELECT queries to get the ForeignKey and 1 INSERT query.


As an example:

Models (using automatic ID fields):

class Customer(models.Model):
    name = models.CharField(max_length=100, blank=False)
    joined = models.DateTimeField(auto_now_add=True)

class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    timestamp = models.DateTimeField()
    price = models.FloatField()

POST data to api/orders/:

[
  {
    "customer": 13,
    ...
  },
  {
    "customer": 14,
    ...
  },
  {
    "customer": 14,
    ...
  }
]

This would result in 3 SELECT statements to get the Customer for each of the Orders, followed by 1 INSERT statement to push the data in.


Similar to prefetch_related() for queries when fetching data in GET requests, is there any way to avoid performing so many queries when deserializing and validating (such as setting the serializer to prefetch foreign keys)?

Kyle McNally
  • 104
  • 2
  • 12
  • 1
    Please post your serializer classes. – Sachin Sep 07 '18 at 14:43
  • [This](https://github.com/encode/django-rest-framework/blob/master/rest_framework/relations.py#L263) is the method call that is messing with you. You can't do anything until you create a custom field to store the queryset and filter it by yourself. – Sachin Sep 07 '18 at 16:09
  • Or, you can override `is_valid` method on serializer to validate. – Sachin Sep 07 '18 at 16:13

0 Answers0