django的admin速度慢优化:date_hierarchy、list_filter

针对一个包含180万条数据的Django后台系统,通过使用django-debug-toolbar定位慢查询,优化ModelAdmin中的list_filter和date_hierarchy选项,将页面加载时间从10多秒缩短至2秒。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目是一个django的后台系统,有一个表大概有180万条数据,打开页面基本要10多秒,自己都要受不了了。第一次尝试对项目进行优化。

首先查到用django-debug-toolbar查询了下那些sql语句耗时。

django-debug-toolba文档:https://django-debug-toolbar.readthedocs.io/en/latest/installation.html

可以看到sql查询一共耗时大概10秒。

 

主要是这四条sql语句耗时:

1、django分页sql:

SELECT COUNT(*) AS `__count` FROM `push_rule` WHERE (`push_rule`.`deleted` = 0 AND `push_rule`.`id` > 0)

 

2、 自定义ModelAdmin中list_filter的字段sql:

SELECT DISTINCT `push_rule`.`operator` FROM `push_rule` WHERE (`push_rule`.`deleted` = 0 AND `push_rule`.`id` > 0) ORDER BY `push_rule`.`operator` ASC

 

 3、自定义ModelAdmin的date_hierarchy选项sql:

SELECT MAX(`push_rule`.`insert_time`) AS `last`, MIN(`push_rule`.`insert_time`) AS `first` FROM `push_rule` WHERE (`push_rule`.`deleted` = 0 AND `push_rule`.`id` > 0)

 

 4、还是自定义ModelAdmin的date_hierarchy选项sql:

SELECT DISTINCT CAST(DATE_FORMAT(`push_rule`.`insert_time`, '%Y-%m-%d 00:00:00') AS DATETIME) AS `datetimefield` FROM `push_rule` WHERE (`push_rule`.`deleted` = 0 AND `push_rule`.`id` > 0 AND `push_rule`.`insert_time` BETWEEN '2019-01-01 00:00:00.000000' AND '2019-12-31 23:59:59.999999' AND EXTRACT(MONTH FROM `push_rule`.`insert_time`) = 7 AND `push_rule`.`insert_time` IS NOT NULL) ORDER BY `datetimefield` ASC

 


第一条暂未优化。

第二条重写一个OperatorFilter:

不从大表push_rule里查询文章的Operaor,直接从django自带的User模型类中查询Operator,User模型里的auth_user表一共也就几百个人,几乎是不用耗时的。不过也也会有点问题,User中展示的是所有user,而push_rule查到的是所有发布的文章中的所有所有作者,有些差别,不过问题不大。

OperatorFilter代码:

from django.contrib.auth.models import User

class OperatorFilter(admin.SimpleListFilter):
    title = _('Who')
    parameter_name = 'operator'


    def lookups(self, request, model_admin):
        staff_operator_set = User.objects.filter(is_staff=1)
        return [(c,c) for c in sorted(staff_operator_set)]

    def queryset(self, request, queryset):
        return queryset.filter(operator=self.value()) if self.value() else queryset

设置list_filter: 

list_filter  = (OperatorFilter)

第三条第四条都是date_hierarchy的问题所以一起处理,这个date_hierarchy最耗时间:

搜索到了大神写好的解决方案:

https://hakibenita.com/scaling-django-admin-date-hierarchy?source=post_page---------------------------

这位大神写了好多django优化的文章。

没看原理,直接拿来用了。

1、安装写好的包django-admin-lightweight-date-hierarchy:

pip install django-admin-lightweight-date-hierarchy

安装要求:

Python 2.7, 3.4, 3.5, 3.6

Django 1.9, 1.10, 1.11, 2.0

2、注册INSTALL_APP

INSTALLED_APPS = (
    'django_admin_lightweight_date_hierarchy',
)

3、自定义ModelAdmin中设置:date_hierarchy_drilldown = False

class MyModelAdmin(admin.ModelAdmin):
  date_hierarchy = 'created'
  date_hierarchy_drilldown = False

到此本次优化基本结束:

再看一下耗时:

 

优化到2秒了,只剩django分页sql的比较耗时了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值