Skip to content

Instantly share code, notes, and snippets.

@safar
Forked from ketanbhatt/admin.py
Last active February 8, 2019 10:42
Show Gist options
  • Save safar/3bbf96678f3e479b6cb683083d35cb4d to your computer and use it in GitHub Desktop.
Save safar/3bbf96678f3e479b6cb683083d35cb4d to your computer and use it in GitHub Desktop.
Large Table Paginator for Django 1.10 and above
from django.contrib.admin import ModelAdmin
class MyTableAdmin(ModelAdmin):
...
paginator = LargeTablePaginator
...
from django.core.paginator import Paginator
from django.utils.functional import cached_property
class LargeTablePaginator(Paginator):
"""
Warning: Postgresql only hack
Overrides the count method of QuerySet objects to get an estimate instead of actual count when not filtered.
However, this estimate can be stale and hence not fit for situations where the count of objects actually matter.
"""
@cached_property
def count(self):
"""
Returns an estimated number of objects, across all pages.
"""
if not self.object_list.query.where:
try:
cursor = connection.cursor()
cursor.execute(
"SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table]
)
estimate = int(cursor.fetchone()[0])
return estimate
except:
# If any exception occurred fall back to default behaviour
return super(LargeTablePaginator, self).count
@noviluni
Copy link

noviluni commented Feb 8, 2019

I think that there is an error. If self.object_list_query.where is True shouldn't we return the super.count()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment