0

I'm using DRF's example of multiple updates which works fine except every self.child.update is a separate update query to the database.

Is there a way I can rewrite this to call the updates as one query as a bulk update?

class BookListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data):
        book_mapping = {book.id: book for book in instance}
        data_mapping = {item['id']: item for item in validated_data}

        ret = []
        for book_id, data in data_mapping.items():
            book = book_mapping.get(book_id, None)
            ret.append(self.child.update(book, data))

        return ret

class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField()

    class Meta:
        list_serializer_class = BookListSerializer
lennard
  • 523
  • 6
  • 19
  • 2
    there is a recipe here https://levelup.gitconnected.com/really-fast-bulk-updates-with-django-rest-framework-43594b18bd75#1891 – Anentropic Oct 21 '22 at 15:14
  • thanks, i did see this example but misunderstood a few things. A bit more digging into the source code it makes a bit more sense now. Thanks – lennard Oct 21 '22 at 15:21
  • Does this answer your question? [How to 'bulk update' with Django?](https://stackoverflow.com/questions/12661253/how-to-bulk-update-with-django) – Shayan Oct 21 '22 at 19:17

2 Answers2

0

Django has a command bulk_update
Docs: https://docs.djangoproject.com/en/4.1/ref/models/querysets/#bulk-update

I'd write up a full example but I'm not sure what validated_data looks like

Nealium
  • 2,025
  • 1
  • 7
  • 9
0
A few suggestions:

 - Use ModelSerializer, as mentioned. It will handle updates/creates automatically and more efficiently.
 - Use model validation (clean methods) instead of serializer validation for database-level validation.
 - Use bulk_create for the creation case (instead of a loop).
 - Use select_related/prefetch_related to reduce queries when fetching the instance.
 - Use .update() or F-expressions to update fields, instead of re-getting the instance from the DB.
 - Use partial=True on the serializer if you expect partial updates.