Почти на всех больших проектах мне удавалось избегать использования
.raw(), по этому я спросил вас, что там внутри. Почти наверняка есть обходные пути.
Для того, чтобы быть уверенным, что запрос не будет выполнен несколько раз, его можно сразу превратить в список:
object_list = list(MyModel.objects.raw(...))
Для выполнения prefetch_related в raw запросах обычно используют
prefetch_related_objects, хотя эта функция в Django не документирована:
from django.db.models.query import prefetch_related_objects
object_list = list(MyModel.objects.raw(...))
prefetch_related_objects(raw_qs, ['fk_field', 'another_fk_field', ...])
Для изучения когда и какие запросы выполняются удобно пользоваться консолью
debugsqlshell из
django debug toolbar (которую вы скорее всего используете).