Виллем прав, что select_related()
уменьшит количество запросов к базе данных, но на самом деле вы должны попытаться перенести свои вычисления в базу данных с использованием агрегатов Django.
from django.db.models import Count, F, Sum
def calc_progress(self):
agg = (
self.child_links
.order_by()
.annotate(
progress=F('goal__weight') * F('goal__progress')
)
.aggregate(
progress_sum=Sum('progress'),
weight_sum=Sum('goal__weight'),
count=Count('id'),
)
)
progress = agg['progress_sum'] / agg['weight_sum'] / agg['count']
self.progress = int(progress)
Это не проверено,поэтому могут потребоваться некоторые настройки, но общая идея заключается в том, что эти вычисления будут более эффективными, если они будут выполнены в базе данных, и select_related()
больше не потребуется.Эта функция выполняет только один запрос к базе данных.
Вы можете найти этот Шпаргалку по оптимизации Django ORM Я написал полезный для подобных ситуаций.