We have a student and class many to many relation, where a student can take multiple classes, and a class can be taken by multiple students.
class Class(models.Model):
name = models.CharField(null=False, max_length=128)
class Student(models.Model):
first_name = models.CharField(null=False, max_length=64)
classes = ManyToManyField(Class)
What is the fastest way to add some object or a whole QueryList
(in our case: all classes with Biology in their name), to the ManyToManyField
of each object in another QueryList
(in our case: all students whose first name is Linus)?
The current way I am doing it is:
biology_classes = Class.objects.filter(name__contains='Biology')
linuses = Student.object.filter(first_name='Linus')
for linus in linuses:
linus.classes.add(*biology_classes)
Which I guess hits the db for each student. I wonder if there is maybe some way to do it all "at once". Maybe something that looks something like this:
linuses.classes.add(*biology_classes) # (this does not work)
You can bulk create a record for each combination with a single query:
biology_classes = Class.objects.filter(name__contains='Biology')
linuses = Student.object.filter(first_name='Linus')
StudentClass = Student.classes.through
items = [
StudentClass(student=student, class=class)
for student in linuses
for class in biologoy_classes
]
StudentClass.objects.bulk_create(items)
This thus will make a total of three queries:
Class
es;Student
s; andClass
es and Student
s.