0

I have:

class Teacher(models.Model):
    name = models.CharField(...)
    ...

class Student(models.Model):
    age = models.IntegerField(...)
    teacher = models.ForeignKey(Teacher, ...)
    ...

I have a queryset of teachers:

teachers = Teacher.objects.filter(name="Betty")

I want to find all of the students related to each teacher in that queryset, and I need the result to be grouped by teacher. Something like:

{
    <Teacher: 1>: [<Student: 1>, <Student: 2>],
    <Teacher: 2>: [<Student: 3>, <Student: 4>]
}

I could accomplish this by just looping over every object in the teachers queryset and filtering Students by students that ForeignKey to that teacher, but that seems really slow and would require an additional DB call for each object. Is there any way to accomplish this in just one or a few DB calls, ideally while staying Python-only and not resorting to SQL?

  • Possible duplicate of [What's the difference between select\_related and prefetch\_related in Django ORM?](https://stackoverflow.com/questions/31237042/whats-the-difference-between-select-related-and-prefetch-related-in-django-orm) – coler-j Apr 04 '19 at 23:20

1 Answers1

3

I'm pretty sure this is the entire point of select_related and prefetch_related. Here is the explanation for select_related:

Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query. This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.

So you would do something like this:

teachers = Teacher.objects.filter(name="betty").prefetch_related("student_set")  # student_set OR whatever is in your related_name field
Hybrid
  • 6,741
  • 3
  • 25
  • 45