How to speed up Django's admin pages with Post

2019-07-07 07:18发布

It's quite known that Django's admin list views are getting rather slow when the database tables have lots of rows. That's because the Django paginator uses by default a (slow) PostgreSQL COUNT query.

As estimate would be fine for us and it's much faster, e.g.: SELECT reltuples FROM pg_class WHERE relname = "my_table_name"

There is snippet available to fix this issue, but it's unclear to me how to actually use it: https://djangosnippets.org/snippets/2593/

Also, the snippet is not supposed to work on filtered results. That's because the estimate count as shown above doesn't work here. Is there another way to speed up filtered list views in Django admin pages?

2条回答
Rolldiameter
2楼-- · 2019-07-07 07:34

You use it by overriding the ModelAdmin.paginator

The paginator class to be used for pagination. By default, django.core.paginator.Paginator is used. If the custom paginator class doesn’t have the same constructor interface as django.core.paginator.Paginator, you will also need to provide an implementation for ModelAdmin.get_paginator().

class MyModelAdmin(admin.ModelAdmin):
    paginator = CachingPaginator

Bonus feature: I have improved on that snippet to create one that works with and without filters: https://gist.github.com/e4c5/6852723 it gets the count from rel_tuples when possible but when a filter is used the count is saved to the cache.

Update 1:
The problem with the original snippet reffered to in your answer is due to this change announced in the 1.6 release notes: https://docs.djangoproject.com/en/1.10/releases/1.6/#get-query-set-and-similar-methods-renamed-to-get-queryset

It's a trivial fix.

update 2
My improvement to the original snippet has been made some what obsolete by the _count propert being renamed to count and also it being decorated as a cached_property

查看更多
祖国的老花朵
3楼-- · 2019-07-07 07:56

There is an option to choose the desired behaviour since Django 1.8: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.show_full_result_count

Example:

class MyModelAdmin(admin.ModelAdmin):
    show_full_result_count = False
查看更多
登录 后发表回答