问题
Let's say I have two different apps :
teacher/models.py:
Teacher(models.Model):
name = models.CharField(max_length=300)
class/models.py:
Class(models.Model):
name = models.CharField(max_length=300)
teacher = models.ForeignKey(Teacher)
students = models.ManyToManyField(Student)
I want to get all the teachers with classes and all classes attached.
The result I want:
{[
teacher: '3L' #Teachers Id
classes: ['20L','14L','30L'] #list of Class objects or ids with the above teacher
],
[# similar to above]
}
Is this possible to do? This is what I am currently doing:
classes = Class.objects.all()
teachers = Teacher.objects.filter(id__in=classes.value_list('teacher',flat=True).distinct())
for teacher in teachers:
classes_for_teachers = classes.objects.filter(teacher=teacher)
In the above code, there are four queries made with a loop which certainly increases the time complexity. Is there a better solution to this? Thanks in advance.
回答1:
Use prefetch_related:
teachers = Teacher.objects.prefetch_related('class_set')
# what you want is not a valid Python structure (set of lists (looking like dicts))
# list of dicts makes more sense
result = [
{'teacher': t.pk, 'classes': t.class_set.all()}
for t in teachers
]
This will only trigger 2 db queries regardless of how many teachers and classes there are.
来源:https://stackoverflow.com/questions/52734174/django-multiple-queries-with-foreign-keys