问题描述
我们有一个学生和一个班级的多对多关系,一个学生可以选多个班级,一个班级可以由多个学生选课。
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)
因此这将总共进行三个查询:
- 一个获取相关
Class
es的查询; - 一个查询来获取相关的
Student
;和 - 在
Class
es 和Student
s 之间创建所有连接的查询。