Django

Code

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

File 0005-Improve-the-new-paginator.2.diff, 5.9 kB (added by Alberto GarcĂ­a Hierro <fiam@rm-fr.net>, 2 years ago)

Improved version of the patch

  • 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        if not self.curpage.has_other_pages(): 
     31            return u'' 
     32 
     33        markup = '<%s class="pagelist">' % el 
     34 
     35        markup += '%s<%s class="prev-next">' % (subel_open, el) 
     36        if self.curpage.has_previous(): 
     37            markup += '%s<a href="%s">&laquo; %s</a>%s' % \ 
     38                    (subel_open, self.curpage.previous_page_url(), 
     39                    _('Previous'), subel_close) 
     40        if self.curpage.has_next(): 
     41            markup += '%s<a href="%s">%s &raquo;</a>%s' % \ 
     42                    (subel_open, self.curpage.next_page_url(), 
     43                    _('Next'), subel_close) 
     44        markup += '</%s>%s' % (el, subel_close) 
     45         
     46        num_pages = self.curpage.paginator.num_pages 
     47        midstart = max(self.curpage.number - self.adjacent_count, 1) 
     48        midend = min(self.curpage.number + self.adjacent_count, num_pages) 
     49 
     50        if midstart > 1: 
     51            end = min(self.adjacent_count + 1, midstart - 1) 
     52            markup += '%s<%s class="start">' % (subel_open, el) 
     53            markup += self._add_range_as_element(subel_open, 
     54                    subel_close, 1, end) 
     55            markup += '</%s>%s' % (el, subel_close) 
     56 
     57        markup += '%s<%s class="middle">' % (subel_open, el) 
     58        markup += self._add_range_as_element(subel_open, subel_close, 
     59                    midstart, midend) 
     60        markup += '</%s>%s' % (el, subel_close) 
     61 
     62        if midend < num_pages: 
     63            start = max(num_pages - self.adjacent_count, midend + 1) 
     64            markup += '%s<%s class="end">' % (subel_open, el) 
     65            markup += self._add_range_as_element(subel_open, subel_close, 
     66                    start, self.curpage.paginator.num_pages) 
     67            markup += '</%s>%s' % (el, subel_close) 
     68 
     69        markup += '</%s>' % el 
     70 
     71        return mark_safe(markup) 
     72 
     73    def as_ul(self): 
     74        return self._as_html('ul', '<li>', '</li>') 
     75 
     76    def as_div(self): 
     77        return self._as_html('div', '', '') 
     78 
     79 
    480class Paginator(object): 
    5     def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True): 
     81    def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True, base_url=None, page_suffix=None, adjacent_count=2, current=None): 
    682        self.object_list = object_list 
    783        self.per_page = per_page 
    884        self.orphans = orphans 
    985        self.allow_empty_first_page = allow_empty_first_page 
     86        self.base_url = base_url 
     87        self.page_suffix = page_suffix 
     88        self.curpage = current 
     89        self.adjacent_count = adjacent_count 
    1090        self._num_pages = self._count = None 
    1191 
    1292    def validate_number(self, number): 
     
    31111        top = bottom + self.per_page 
    32112        if top + self.orphans >= self.count: 
    33113            top = self.count 
     114        if self.curpage is None: 
     115            self.curpage = number 
    34116        return Page(self.object_list[bottom:top], number, self) 
    35117 
     118    def page_or_404(self, number): 
     119        try: 
     120            return self.page(number) 
     121        except InvalidPage: 
     122            raise Http404(_('Invalid page')) 
     123 
    36124    def _get_count(self): 
    37125        "Returns the total number of objects, across all pages." 
    38126        if self._count is None: 
     
    61149        return range(1, self.num_pages + 1) 
    62150    page_range = property(_get_page_range) 
    63151 
     152    def _get_page_list(self): 
     153        return PageList(self) 
     154    page_list = property(_get_page_list) 
     155 
    64156class QuerySetPaginator(Paginator): 
    65157    """ 
    66158    Like Paginator, but works on QuerySets. 
     
    95187    def previous_page_number(self): 
    96188        return self.number - 1 
    97189 
     190    def next_page_url(self): 
     191        return Page(self.object_list, self.number + 1, self.paginator).url() 
     192 
     193    def previous_page_url(self): 
     194        return Page(self.object_list, self.number - 1, self.paginator).url() 
     195 
     196    def url(self): 
     197        if self.number == 1: 
     198            return self.paginator.base_url 
     199 
     200        return self.paginator.base_url + self.paginator.page_suffix % self.number 
     201 
    98202    def start_index(self): 
    99203        """ 
    100204        Returns the 1-based index of the first object on this page,