Ticket #6860: 0005-Improve-the-new-paginator.diff

File 0005-Improve-the-new-paginator.diff, 6.1 KB (added by Alberto García Hierro <fiam@…>, 16 years ago)
  • django/core/paginator.py

    From c55f6da7d921b6b7033b398d4f7d81231ee0dec2 Mon Sep 17 00:00:00 2001
    From: =?utf-8?q?Alberto=20Garc=C3=ADa=20Hierro?= <fiam@rm-fr.net>
    Date: Sun, 23 Mar 2008 05:18:27 +0100
    Subject: [PATCH] Improve the new paginator.
    
    Add methods for storing the base_url and retrieving it,
    displaying the page list as ul or div (taking the
    current page into account) as well as for obtaining
    the links for the previous and next pages.
    ---
     django/core/paginator.py |  106 +++++++++++++++++++++++++++++++++++++++++++++-
     1 files changed, 105 insertions(+), 1 deletions(-)
    
    diff --git a/django/core/paginator.py b/django/core/paginator.py
    index dabd20d..ba3ed18 100644
    a b  
     1from django.utils.translation import ugettext as _
     2from django.utils.safestring import mark_safe
     3from django.http import Http404
     4
    15class InvalidPage(Exception):
    26    pass
    37
     8class PageList(object):
     9    def __init__(self, paginator):
     10        self.curpage = paginator.page(paginator.curpage)
     11        self.adjacent_count = paginator.adjacent_count
     12
     13    def __repr__(self):
     14        return '<PageList current: %d - total:%d>' % \
     15            (self.curpage.paginator.curpage, self.curpage.paginator.num_pages)
     16
     17    def _add_range_as_element(self, open, close, start, end):
     18        markup = ''
     19        for i in range(start, end + 1):
     20            page = self.curpage.paginator.page(i)
     21            if self.curpage.number == i:
     22                markup += '%s<a class="curpage">%d</a>%s' % \
     23                    (open, i, close)
     24            else:
     25                markup += '%s<a href="%s">%d</a>%s' % \
     26                    (open, page.url(), i, close)
     27        return markup
     28
     29    def _as_html(self, el, subel_open, subel_close):
     30        markup = '<%s class="pagelist">' % el
     31        if self.curpage.has_previous() or self.curpage.has_next():
     32            markup += '%s<%s class="prev-next">' % (subel_open, el)
     33            if self.curpage.has_previous():
     34                markup += '%s<a href="%s">&laquo; %s</a>%s' % \
     35                        (subel_open, self.curpage.previous_page_url(),
     36                         _('Previous'), subel_close)
     37            if self.curpage.has_next():
     38                markup += '%s<a href="%s">%s &raquo;</a>%s' % \
     39                        (subel_open, self.curpage.next_page_url(),
     40                        _('Next'), subel_close)
     41            markup += '</%s>%s' % (el, subel_close)
     42        else:
     43            return u''
     44
     45        markup += '%s<%s class="start">' % (subel_open, el)
     46        end = self.adjacent_count + 1
     47        if end > self.curpage.paginator.num_pages:
     48            end = self.curpage.paginator.num_pages
     49        if end == self.curpage.number:
     50            end -= 1
     51        markup += self._add_range_as_element(subel_open, subel_close, 1, end)
     52        markup += '</%s>%s' % (el, subel_close)
     53
     54        if self.curpage.number > self.adjacent_count:
     55            midstart = self.curpage.number - self.adjacent_count
     56            if midstart <= self.adjacent_count:
     57                midstart = self.adjacent_count + 1
     58            midend = self.curpage.number + self.adjacent_count
     59            if midend > self.curpage.paginator.num_pages:
     60                midend = self.curpage.paginator.num_pages
     61            markup += '%s<%s class="middle">' % (subel_open, el)
     62            markup += self._add_range_as_element(subel_open, subel_close,
     63                    midstart, midend)
     64            markup += '</%s>%s' % (el, subel_close)
     65
     66
     67        start = self.curpage.paginator.num_pages - self.adjacent_count
     68        if start > self.adjacent_count and start > self.curpage.number + self.adjacent_count:
     69            markup += '%s<%s class="end">' % (subel_open, el)
     70            markup += self._add_range_as_element(subel_open, subel_close,
     71                    start, self.curpage.paginator.num_pages)
     72            markup += '</%s>%s' % (el, subel_close)
     73        markup += '</%s>' % el
     74
     75        return mark_safe(markup)
     76
     77    def as_ul(self):
     78        return self._as_html('ul', '<li>', '</li>')
     79
     80    def as_div(self):
     81        return self._as_html('div', '', '')
     82
     83
    484class Paginator(object):
    5     def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True):
     85    def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True, base_url=None, adjacent_count=2, current=None):
    686        self.object_list = object_list
    787        self.per_page = per_page
    888        self.orphans = orphans
    989        self.allow_empty_first_page = allow_empty_first_page
     90        self.base_url = base_url
     91        self.curpage = current
     92        self.adjacent_count = adjacent_count
    1093        self._num_pages = self._count = None
    1194
    1295    def validate_number(self, number):
    class Paginator(object):  
    31114        top = bottom + self.per_page
    32115        if top + self.orphans >= self.count:
    33116            top = self.count
     117        if self.curpage is None:
     118            self.curpage = number
    34119        return Page(self.object_list[bottom:top], number, self)
    35120
     121    def page_or_404(self, number):
     122        try:
     123            return self.page(number)
     124        except InvalidPage:
     125            raise Http404(_('Invalid page'))
     126
    36127    def _get_count(self):
    37128        "Returns the total number of objects, across all pages."
    38129        if self._count is None:
    class Paginator(object):  
    61152        return range(1, self.num_pages + 1)
    62153    page_range = property(_get_page_range)
    63154
     155    def _get_page_list(self):
     156        return PageList(self)
     157    page_list = property(_get_page_list)
     158
    64159class QuerySetPaginator(Paginator):
    65160    """
    66161    Like Paginator, but works on QuerySets.
    class Page(object):  
    95190    def previous_page_number(self):
    96191        return self.number - 1
    97192
     193    def next_page_url(self):
     194        return self.paginator.base_url % self.next_page_number()
     195
     196    def previous_page_url(self):
     197        return self.paginator.base_url % self.previous_page_number()
     198
     199    def url(self):
     200        return self.paginator.base_url % self.number
     201
    98202    def start_index(self):
    99203        """
    100204        Returns the 1-based index of the first object on this page,
Back to Top