Я создаю приложение, в котором перечислены эпизоды и категории для подкаста. Отношения модели устанавливаются таким образом
models.py
class Podcast(models.Model):
...
@property
def episodes_by_category(self):
category_list = []
for category in self.category_set.all():
category_list.append({
'category': category,
'episodes': self.episode_set.all().filter(categories=category),
'count': self.episode_set.all().filter(categories=category).count(),
})
return sorted(category_list, key = lambda i: i['count'],reverse=True)
class Category(models.Model):
...
podcast = models.ForeignKey(Podcast, on_delete=models.CASCADE)
...
def get_absolute_url(self):
kwargs = {
'slug': self.podcast.slug,
'category_slug': self.slug
}
return reverse('category_page', kwargs=kwargs)
class Episode(models.Model):
...
podcast = models.ForeignKey(Podcast, on_delete=models.CASCADE)
categories = models.ManyToManyField(Category)
...
def get_absolute_url(self):
kwargs = {
'show_slug': self.podcast.slug,
'pk': self.id,
'slug': self.slug
}
return reverse('episode_page', kwargs=kwargs)
На странице подкаста я использую episodes_by_category, чтобы показать список категорий, каждая с несколькими эпизодами
В DetailView
Это вызывает значительное количество запросов к базе данных. Вот как это происходит:
views.py
class PodcastPage(DetailView):
model = Podcast
template_name = 'dashboard/public/podcast_page.html'
def get_context_data(self, **kwargs):
context = super(PodcastPage, self).get_context_data(**kwargs)
context['episodes'] = self.get_object().get_episodes[:10].prefetch_related('categories')
return context
podcast_page. html
{% for episode_batch in podcast.episodes_by_category %}
<div class="sidebar-object">
<div class="section-title section-title--style-1 mb-0">
<h3 class="section-title-inner heading-sm strong-600 text-uppercase">
Top <a href="{{episode_batch.category.get_absolute_url}}" class="link">{{episode_batch.category.name|title}}</a> Episodes
</h3>
</div>
<ul class="categories list-border--dotted">
{% for episode in episode_batch.episodes %}
{% if forloop.counter < 4 %}
<li>
<a href="{{episode.get_absolute_url}}">{{episode.name}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endfor %}
Что я могу оптимизировать в этом логике c, чтобы сделать его более эффективнее и меньше попадать в базу?