Django

Code

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@rm-fr.net>, 10 months ago)
  • a/django/core/paginator.py

    old new  
     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): 
     
    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: 
     
    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. 
     
    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,