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)
This code represents what I am doing.
Why is the line k = model.m2m_model_set.all().values_list('field')
causing many queries?
How can I fix this problem and do the same without making so many queries?
1
If you further filter, select, aggregate on the queryset, it requires again making queries one per item. The .prefetch_related
fetches the related manager in one extra query, but thus that query, additional filtering and so on can not be done with that.
The good news is that we can alter the queryset that Django uses:
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()]
But you probably should not use the ManyToManyField
, you can trigger the model in reverse, so:
MyOtherModel.objects.filter(mymodel__isnull=False).distinct()
will fetch the MyOtherModel
s for which there exists a MyModel
object.