Django Admin列表页卡顿的根本原因是后端低效查询:外键字段触发全表SELECT、每行调用__str__、双下划线字段未加select_related,导致100条记录发起300+次查询。

为什么 Django Admin 列表页一查就卡?
根本原因不是前端渲染慢,而是后端默认执行了大量低效查询:每个外键字段触发一次全表 SELECT、列表页每行都调用 __str__、list_display 里带双下划线的字段(如 author__name)没加 select_related —— 这些叠加起来,100 条记录可能发起 300+ 次数据库查询。
禁用 list_editable,除非你真需要它
list_editable 是 Admin 里最隐蔽的性能杀手。它会让 Django 为每行每个可编辑字段重新构造表单实例,外键字段会再次查一遍关联表,50 行数据就能让响应时间从 200ms 跳到 4s+。
- 绝对不要对外键、
ManyToManyField或动态choices字段启用list_editable - 如果只是想批量改状态,用
actions更轻量:queryset.update(is_active=True)绕过 ORM 实例化 - 必须用时,搭配
list_per_page = 20,并重写get_list_editable()动态控制权限或条件
外键下拉框卡死?别让它查全表
Admin 默认对 ForeignKey 字段使用 ModelChoiceField,底层是 queryset.all()。几万条用户数据,页面加载直接卡在 SQL 层。
- 首选方案:
autocomplete_fields = ['user'],配合模型上定义search_fields = ['username', 'email']和数据库索引 - 必须保留下拉框时,在
get_form()里手动限制 queryset:form.base_fields['user'].queryset = User.objects.filter(is_active=True) - 避免在
formfield_for_foreignkey里做任何数据库查询或 API 调用——它会在每次页面渲染时执行 N 次
缓存和懒加载能救急,但别迷信
路由缓存、查询结果缓存这些听起来很美,但在 Admin 场景下容易踩坑:
-
cache_page对 Admin 视图基本无效,因为它是基于 URL 的,而 Admin 的列表页 URL 带分页、搜索参数,缓存命中率极低 - 对
get_queryset做缓存需谨慎:如果后台数据实时更新频繁,缓存反而导致管理员看到脏数据 - 路由缓存(如
CachedResolver)只在项目路由极其庞大(>500 条)时才有明显收益,中小项目加了反而多一层故障点
真正该优先做的,永远是砍掉不必要的查询——比如删掉没用的 list_filter、关掉 search_fields、把 list_display_links = None,这些改动一行配置就能见效,比加缓存更直接、更可控。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











