Skip to content

Commit

Permalink
Cache invalidation for paginator implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
Tolga Bilbey committed May 19, 2020
1 parent 34a799d commit a405d76
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ Fast Paginator is a simple Django app to paginate Django Querysets. Core Django
'fast_pagination'
]
```
2. Import FastPaginator like this:
2. In Django settings, you can set FAST_PAGINATION_TIMEOUT variable to invalidate cache. Default value is 1 hour.
3. Import FastPaginator like this:
```python
from fast_pagination.helpers import FastPaginator
```
3. Then, you are ready. All you have to do is give your queryset and number of entries when creating FastPaginator object.
4. Then, you are ready. All you have to do is give your queryset and number of entries when creating FastPaginator object.
28 changes: 20 additions & 8 deletions fast_pagination/helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import inspect
from datetime import datetime

from django.core.paginator import Paginator, Page
from django.core.cache import cache
from django.conf import settings
from django.db.models.query import QuerySet
from django.utils.functional import cached_property
from django.utils.inspect import method_has_no_args


Expand All @@ -11,17 +13,27 @@ class FastPaginator(Paginator):
def __init__(self, object_list, per_page, orphans=0,
allow_empty_first_page=True):
super().__init__(object_list, per_page, orphans, allow_empty_first_page)
self.cache_key = self.get_paginator_cache_key()
self.timeout = getattr(settings, "FAST_PAGINATION_TIMEOUT", 3600)
if isinstance(object_list, QuerySet):
self.ids = list(object_list.values_list('id', flat=True))

@cached_property
def get_paginator_cache_key(self):
return datetime.now().isoformat()

@property
def count(self):
c = getattr(self.object_list, 'count', None)
if callable(c) and not inspect.isbuiltin(c) \
and method_has_no_args(c) \
and not isinstance(self.object_list, QuerySet):
return c()
return len(self.ids)
result = cache.get(self.cache_key)
if result is None:
c = getattr(self.object_list, 'count', None)
if callable(c) and not inspect.isbuiltin(c) \

This comment has been minimized.

Copy link
@miratcan

miratcan May 20, 2020

Contributor

There's no need to check all of these. I think you're only trying to support QuerySets and object lists. Then if you check if object_list is QuerySet you can directly call count, otherwise call len.

and method_has_no_args(c) \
and isinstance(self.object_list, QuerySet):
result = c()
else:
result = len(self.object_list)
cache.set(self.cache_key, result, timeout=self.timeout)
return result

def page(self, number):
number = self.validate_number(number)
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[metadata]
name = django-fast-paginator
version = v1.0.0
version = v1.0.1
description = A Django app to paginate querysets faster.
long_description = file: README.md
long_description_content_type = text/markdown
author = Tolga Bilbey
author_email = [email protected]
license = BSD-3-Clause
url = https://github.com/bilbeyt/django-fast-pagination
download_url = https://github.com/bilbeyt/django-fast-pagination/archive/v1.0.0.tar.gz
download_url = https://github.com/bilbeyt/django-fast-pagination/archive/v1.0.1.tar.gz
keywords =
django
pagination
Expand Down

0 comments on commit a405d76

Please sign in to comment.