from django.core.paginator import Paginator class PaginatorMixin : def digg_page_range(self, page) : BODY_PAGES = 9 MARGIN_PAGES = 3 TAIL_PAGES = 2 position = 1 p, q = TAIL_PAGES, max(1, min(page.number - BODY_PAGES / 2, self.num_pages - BODY_PAGES + 1)) if q - p > MARGIN_PAGES : for x in xrange(position, p + 1) : yield x yield None position = q p, q = q + BODY_PAGES - 1, self.num_pages - TAIL_PAGES + 1 if q - p > MARGIN_PAGES : for x in xrange(position, p + 1) : yield x yield None position = q for x in xrange(position, self.num_pages + 1) : yield x if PaginatorMixin not in Paginator.__bases__ : Paginator.__bases__ = (PaginatorMixin,) + Paginator.__bases__ # # example usage in a custom tag (used from within django.views.generic.list_detail.object_list template): # # @register.inclusion_tag('paginator.html', takes_context = True) # def pages(context) : # page_obj = context['page_obj'] # return {'digg_page_range' : page_obj.paginator.digg_page_range(page_obj), 'page_obj' : page_obj} # # where paginator.html might look like this: # # # {% if page_obj.has_previous %}<{% endif %} # {% for p in digg_page_range %} # {% if not p %}...{% else %}{% ifequal p page_obj.number %}{{p}}{% else %}{{p}}{% endifequal %}{% endif %} # {% endfor %} # {% if page_obj.has_next %}>{% endif %} #