Skip to content

Instantly share code, notes, and snippets.

@obeattie
Created April 2, 2010 06:34
Show Gist options
  • Save obeattie/352843 to your computer and use it in GitHub Desktop.
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.
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