Shellbye.github.io
Shellbye.github.io copied to clipboard
Django related_name prefetch_related 浅析
1.related_name
首先是related_name
,官网是这么说明的:
The name to use for the relation from the related object back to this one.
这个名字是用来反向查找与其有关的对象时使用的
我看过好几次,但是一直没搞明白是啥,知道实际再别人的代码看到具体的使用,才明白。举例说假设你有如下的models.py
文件,用来定义老师与学生:
class Teacher(models.Model):
name = models.CharField(max_length=50)
class Student(models.Model):
name = models.CharField(max_length=50)
tch = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True)
通过学生获取老师是比较直观的,
stu = Student.objects.get(id=1)
tch = stu.tch
反过来要通过老师获取学生,Django官方有相应的操作,但是不是特别直观,
tch = Teacher.objects.get(id=1)
students = tch.student_set.all()
这样的有一个问题就是当一个学生表里有多个老师的外健时,如下:
class Student(models.Model):
name = models.CharField(max_length=50)
tch = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True)
headmaster = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True)
这个反向查找就会报错,因为有两个外健,Django不知道在逆向查找时该找哪一个,这个时候就是related_name
发挥作用的时候了:
class Student(models.Model):
name = models.CharField(max_length=50)
tch = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True, related_name='class_stu')
headmaster = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True, related_name='school_stu')
这时,班级老师要查找学生就可以通过设置好的related_name
进行了:
tch = Teacher.objects.get(id=1)
students = class_stu
而校长则是通过另一个来获取本校的所有学生
tch = Teacher.objects.get(id=1)
students = school_stu
2. prefetch_related
有了related_name
,可以方便的反向查找与其关联的对象,但是因为要多次方法数据库,效率不够高,所以就有了prefetch_related