Могу ли я получить связанные данные напрямую при использовании запроса join в django?

Хорошо рассмотрим две модели:

class School(models.Model):
    name = TextField()

class Student(models.Model):
    school = ForeignKey(School
        related_name=students
    )
    firstname = TextField()

А запрос:

School.objects.filter(Q(name="oldschool") & Q(
    Q(students__firstname="hello") | Q(students__firstname="testname")
))

Я получаю данные о школах. Однако явно выполняется запрос join/subquery, но я не получаю информацию об учениках. Я также хочу получить информацию об учениках, для которых установлено "первое имя".

Могу ли я сделать так, чтобы django orm действительно заполнял students_set, чтобы мне не приходилось потом делать несколько поисков (перебирать школы и проверять каждую школу).

Обычно это делается с помощью .prefetch_related(…) [Django-doc]:

from django.db.models import Prefetch

schools = School.objects.filter(
    Q(students__firstname='hello') | Q(students__firstname='testname'),
    name='oldschool',
).prefetch_related(
    Prefetch(
        'students',
        Student.objects.filter(Q(firstname='hello') | Q(firstname='testname')),
    )
)

for school in schools:
    for student in school.students.all():
        print(student)

это сделает один дополнительный запрос для всех Studentс для всех Schoolс, таким образом два запроса. Это сделано для того, чтобы уменьшить пропускную способность канала от базы данных к слою Django/Python.

Однако если есть только одна школа, то логичнее делать запрос из представления Student:

Student.objects.filter(
    Q(firstname='hello') | Q(firstname='testname'), school__name='oldschool'
)

Тогда мы можем также включить School данные, но это, вероятно, не хорошая идея:

Student.objects.filter(
    Q(firstname='hello') | Q(firstname='testname'), school__name='oldschool'
).select_related('school')
Вернуться на верх