-
-
Save safar/3bbf96678f3e479b6cb683083d35cb4d to your computer and use it in GitHub Desktop.
Large Table Paginator for Django 1.10 and above
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.contrib.admin import ModelAdmin | |
class MyTableAdmin(ModelAdmin): | |
... | |
paginator = LargeTablePaginator | |
... | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think that there is an error. If
self.object_list_query.where
isTrue
shouldn't we return thesuper.count()
?