Django prefetch_related не помогает при уменьшении запросов

myList = []
qs = MyModel.objects.all().prefetch_related('m2m_model_set')
for model in qs:
    k = model.m2m_model_set.all().values_list('field')
    myList.extend(k)

Этот код представляет то, что я делаю. Почему строка k = model.m2m_model_set.all().values_list('field') вызывает много запросов? Как я могу решить эту проблему и сделать то же самое, не делая так много запросов?

Если вы будете далее фильтровать, выбирать, агрегировать набор запросов, это снова потребует выполнения запросов по одному на элемент. .prefetch_related собирает связанный менеджер в один дополнительный запрос, но, таким образом, этот запрос, дополнительная фильтрация и т. д. не могут быть сделаны с ним.

Хорошая новость заключается в том, что мы можем изменить набор запросов, который использует Django:

from django.db.models import Prefetch

myList = []
qs = MyModel.objects.prefetch_related(
    Prefetch('m2m_model_set', myOtherModel.objects.only('field'))
)
for model in qs:
    myList += [m.field for m in model.m2m_model_set.all()]

Но вам, вероятно, не стоит использовать ManyToManyField, вы можете запустить модель в обратном направлении, так:

MyOtherModel.objects.filter(mymodel__isnull=False).distinct()

будут получены MyOtherModel, для которых существует MyModel объект.

Вернуться на верх