Django custom function taking a long time to run for the view
I have a function below that generates a navigation so it can be using in the view. It is pulling in the articles, article category, and article subcategory. The main issue is that with about 15 category and 46 subcategory and 33 articles it is taking like 7-10 seconds to finish loading this function. What is the best approach for handling this so that it loads faster?
def generate_navigation_list(request):
articles = Article.objects.all()
article_category = ArticleCategory.objects.all()
articles_sub_category = ArticleSubCategory.objects.all()
# Create a navigation list structure
navigation_list = []
# Iterate over categories
for category in article_category:
category_dict = {
'id': category.id,
'title': category.name,
'subcategory': []
}
# Filter subcategories for the current category
filtered_subcategories = articles_sub_category.filter(category=category)
# Iterate over filtered subcategories
for subcategory in filtered_subcategories:
subcategory_dict = {
'id': subcategory.id,
'title': subcategory.name,
'articles': []
}
# Filter articles for the current subcategory
filtered_articles = articles.filter(sub_category=subcategory).order_by('order')
# Add articles to the subcategory dictionary if there are articles
if filtered_articles.exists(): # Check if there are any articles
for article in filtered_articles:
article_dict = {
'title': article.title,
'slug': article.slug
}
subcategory_dict['articles'].append(article_dict)
# Append subcategory dictionary to category dictionary
category_dict['subcategory'].append(subcategory_dict)
# Append category dictionary to navigation list if it has subcategories with articles
if category_dict['subcategory']:
navigation_list.append(category_dict)
request.session['navigation_list'] = navigation_list
request.session.save()
In the code you wrote, you query articles for each category and subcategory. This means multiple queries are sent to the database. Instead, you can use select_related
and prefetch_related
to retrieve data from the database with fewer queries.
def generate_navigation_list(request):
articles = Article.objects.select_related('sub_category').all()
article_categories = ArticleCategory.objects.prefetch_related('subcategories').all()
navigation_list = []
for category in article_categories:
category_dict = {
'id': category.id,
'title': category.name,
'subcategory': []
}
# Iterate over subcategories
for subcategory in category.subcategories.all():
subcategory_dict = {
'id': subcategory.id,
'title': subcategory.name,
'articles': []
}
filtered_articles = [article for article in articles if article.sub_category == subcategory]
if filtered_articles:
for article in filtered_articles:
article_dict = {
'title': article.title,
'slug': article.slug
}
subcategory_dict['articles'].append(article_dict)
category_dict['subcategory'].append(subcategory_dict)
if category_dict['subcategory']:
navigation_list.append(category_dict)
request.session['navigation_list'] = navigation_list
request.session.save()