Django视图自定义导航生成函数运行缓慢,求优化方案
Django导航生成函数性能优化方案
你的代码慢的核心原因是N+1数据库查询问题——循环里每处理一个分类、子分类都要发起新的数据库请求,15个分类+46个子分类下来,额外触发了几十次查询,这是耗时的主要来源。下面是针对性的优化方案:
1. 用预加载减少数据库查询次数
Django提供了select_related(用于一对一/多对一关联)和prefetch_related(用于一对多/多对多关联),可以一次性把所有需要的关联数据查询出来,避免循环中的重复请求。
修改数据查询部分,直接预加载子分类和关联文章:
from django.db.models import Prefetch def generate_navigation_list(request): # 预加载所有关联数据,指定文章按order排序,只查询需要的字段 article_categories = ArticleCategory.objects.prefetch_related( Prefetch( 'articlesubcategory_set', queryset=ArticleSubCategory.objects.prefetch_related( Prefetch( 'article_set', queryset=Article.objects.order_by('order').only('title', 'slug') ) ) ) ) navigation_list = [] for category in article_categories: category_dict = { 'id': category.id, 'title': category.name, 'subcategory': [] } # 直接用预加载的子分类,不再发起新查询 for subcategory in category.articlesubcategory_set.all(): subcategory_dict = { 'id': subcategory.id, 'title': subcategory.name, 'articles': [] } # 用预加载的文章,无需再次filter articles = subcategory.article_set.all() if articles: for article in 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()
这里用only('title', 'slug')指定只查询需要的字段,避免加载Article模型的冗余数据,进一步提升效率。
2. 缓存导航数据(可选但效果显著)
如果导航内容不是实时更新的,可以把生成好的navigation_list缓存到全局缓存中,不用每次请求都重新生成。比如用Django的缓存框架:
from django.core.cache import cache def generate_navigation_list(request): # 先尝试从缓存获取 navigation_list = cache.get('site_navigation') if not navigation_list: # 执行上面的预加载查询和导航生成逻辑... # 生成后存入缓存,设置过期时间(比如1小时) cache.set('site_navigation', navigation_list, 3600) request.session['navigation_list'] = navigation_list request.session.save()
这样只有第一次请求或者缓存过期时才会执行数据查询和生成逻辑,后续请求直接从缓存读取,耗时会降到毫秒级。
3. 去掉不必要的重复查询
原代码中filtered_articles.exists()会触发一次数据库查询,之后循环filtered_articles又会触发一次。预加载后直接用if articles:判断即可,不会额外发起查询。
内容的提问来源于stack exchange,提问作者Nello
相关产品推荐
相关产品推荐

