Created
April 2, 2010 06:34
-
-
Save obeattie/352843 to your computer and use it in GitHub Desktop.
A Django Paginator implementation that is stupid. It only knows whether it can navigate forward or back, not how many pages are available. Useful for object lists of an unknown length.
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 EmptyPage, InvalidPage, PageNotAnInteger, Page, Paginator | |
class IgnorantPage(Page): | |
"""The just-as-ignorant stepchild of IgnorantPaginator and Page.""" | |
def __init__(self, *args, **kwargs): | |
ret = super(IgnorantPage, self).__init__(*args, **kwargs) | |
# Now, we need to know if we have a first and last dealio | |
self.__has_next = (len(self.object_list) > self.paginator.per_page) | |
self.object_list = self.object_list[:self.paginator.per_page] | |
return ret | |
def has_next(self): | |
return self.__has_next | |
def __repr__(self): | |
return '<Page %s>' % self.number | |
class IgnorantPaginator(Paginator): | |
"""A Paginator implementation that is stupid. It only knows whether it can navigate | |
forward or back, not how many pages are available. Useful for object lists of an | |
unknown length (like when the objects are being fetched from a backend process | |
with no way of calculating the length ahead of time).""" | |
ignoramus = True | |
def __not_a_chance(self, *args, **kwargs): | |
"""Raises a NotImplementedError, in a very ignorant fashion.""" | |
raise NotImplementedError | |
_get_num_pages = __not_a_chance | |
num_pages = property(_get_num_pages) | |
_get_count = __not_a_chance | |
count = property(_get_count) | |
def validate_number(self, number, default=None): | |
try: | |
try: | |
number = int(number) | |
except ValueError: | |
raise PageNotAnInteger | |
if number < 1: | |
raise EmptyPage('That page number is less than 1') | |
return number | |
except InvalidPage: | |
if default is not None: | |
return self.validate_number(number=default) | |
raise | |
def page(self, number, default=None): | |
assert (self.orphans == 0), 'I\'m too ignorant to deal with orphans' | |
number = self.validate_number(number=number, default=default) | |
bottom = ((number - 1) * self.per_page) | |
top = (bottom + self.per_page + 1) | |
# Get the results | |
results = self.object_list[bottom:top] | |
if not results: | |
if number == 1 and self.allow_empty_first_page: | |
pass | |
else: | |
raise EmptyPage('That page contains no results') | |
return IgnorantPage(results, number, self) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment