django - 如何在 select_related 模型上进行注释?
问题描述
我为查询集中的每个对象选择了一个相关对象。如何注释每个计算值?
模型:
class School(models.Model):
name = models.CharField(max_length=255)
class Teacher(models.Model):
name = models.CharField(max_length=255)
school = models.ForeignKey(School)
class Student(Entity):
name = models.CharField(max_length=255)
school = models.ForeignKey(School)
我想获取所有老师以及每个老师的学校以及该学校的学生人数。
这是我尝试过的:
teachers = Teacher.objects.select_related('school').annotate(student_count=Count('school__student'))
但我可以看到这是错误的,因为学生人数必须是每所学校。
我希望之后能够用我的查询集做这样的事情:
for teacher in teachers:
print(teacher.name, teacher.school.name, teacher.school.student_count)
解决方案
但我可以看到这是错误的,因为学生人数必须是每所学校。
好吧,您将计算属于该老师所属学校的学生,因此这在语义上是有效的。然而,注释将放在查询集中的对象上,因此是教师,因此您可以使用以下方法获取学生人数:
for teacher in teachers:
print(teacher.name, teacher.school.name, teacher.student_count)
由于多个老师可以属于同一所学校,以这种方式进行注释可能不是最好的主意,因为如果不优化,这意味着您将为每个老师计算该学校的学生人数。尽管从语义上讲这不会改变任何东西,但查询可能需要相当长的时间。
您可以决定对.prefetch_related(..)
给定使用 a ,并在对象 [Django-doc]school
中注释该查询集,这将导致额外的查询,但成本更低。例如:Prefetch
from django.db.models import Prefetch, Count
teachers = Teacher.objects.prefetch_related(
Prefetch(
'school',
queryset=School.objects.annotate(student_count=Count('student'))
)
)
然后你确实可以查询:
for teacher in teachers:
print(teacher.name, teacher.school.name, teacher.school.student_count)