Django:如何有效地将对象添加到多个对象的 ManyToManyFields 中?

问题描述

我们有一个学生和一个班级的多对多关系,一个学生可以选多个班级,一个班级可以由多个学生选课。

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)

将某个对象或整个 QueryList(在我们的例子中:名称中带有 Biology 的所有类)添加到每个对象的 ManyToManyField 的最快方法是什么?对象在另一个 QueryList(在我们的例子中:所有名字是 Linus 的学生)?

我目前的做法是:

biology_classes = Class.objects.filter(name__contains='Biology')
linuses = Student.object.filter(first_name='Linus')
for linus in linuses:
    linus.classes.add(*biology_classes)

我猜这会为每个学生击中数据库。我想知道是否有某种方法可以“一次”完成所有工作。也许看起来像这样:

linuses.classes.add(*biology_classes) # (this does not work)

解决方法

您可以使用单个查询为每个组合批量创建记录:

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)

因此这将总共进行三个查询:

  1. 一个获取相关Classes的查询;
  2. 一个查询来获取相关的Student;和
  3. Classes 和 Students 之间创建所有连接的查询。