[Fixed]-Create multiple objects without multiple hits to the db in Django 1.8

16👍

You can’t do all of them in one query. However, you are on the right track. You should be using .bulk_create() for batch insertion and do one more lookup for getting them back as objects in order to add into foos.

If you are too concerned that the latter query will perform slowly, you can set unique=True or, db_index=True for improving performance.

You also want to maintain the atomicity of operations using transactions, so that any INSERT fails, all of them should be rolled back:

from django.db import transaction

class Foo(models.Model):
    name = models.CharField(max_length=200, unique=True)

class Bar(models.Model):
    foos = models.ManyToManyField(Foo)

class Processor(object):
    def run(self):
        transaction.set_autocommit(False)
        try:
            myList = ['a', 'b', 'c', 'd']
            Foo.objects.bulk_create([Foo(n) for n in myList])

            myBar = Bar.object.create()
            myBar.foos.add(Foo.objects.filter(name__in=myList))
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
        finally:
            transaction.set_autocommit(True)

Please see Django documentation for more information about autocommit behavior.

Leave a comment