Ticket #4805: 4805-alt.2.diff

File 4805-alt.2.diff, 5.6 KB (added by nick.lane.au@…, 12 years ago)

Alternate implementation based on #2576... that isn't completely broken like the last one I added

  • django/core/paginator.py

    === modified file 'django/core/paginator.py'
     
    8686
    8787    hits = property(_get_hits)
    8888    pages = property(_get_pages)
     89
     90class ObjectPaginatorForPage(object):
     91    """
     92    This class is used to work with a page of a paginator object.
     93    Pass a paginator object, and a valid page number.
     94    It uses the same methods as a paginator, except you do not need
     95    to use a page number, and also provides some other useful
     96    properties.
     97
     98    `page_number` is always 0-based to match the Paginator object.
     99    `base` allows next_page_number, previous_page_number and
     100    page_number return their numbers using a different base.
     101
     102    For example:
     103    self, query_set, num_per_page, orphans=0
     104    >>> paginator = ObjectPaginatorForPage(query_set, num_per_page, 0, base=1)
     105    >>> paginator.next_page_number()
     106    2
     107    >>> paginator.page_number
     108    1
     109    """
     110    def __init__(self, query_set, num_per_page, page_number=0, base=1, orphans=0):
     111        self.paginator = ObjectPaginator(query_set, num_per_page, orphans)
     112        # _page_number remains the base-0 page number
     113        self._page_number = page_number
     114        self.base = base
     115        self.num_per_page = num_per_page
     116
     117    def get_page(self):
     118        if not hasattr(self, '_page'):
     119            self._page = self.paginator.get_page(self._page_number)
     120        return self._page
     121
     122    def has_next_page(self):
     123        return self.paginator.has_next_page(self._page_number)
     124
     125    def has_previous_page(self):
     126        return self.paginator.has_previous_page(self._page_number)
     127
     128    def first_on_page(self):
     129        return self.paginator.first_on_page(self._page_number)
     130
     131    def last_on_page(self):
     132        return self.paginator.last_on_page(self._page_number)
     133
     134    def _get_hits(self):
     135        return self.paginator.hits
     136    hits = property(_get_hits)
     137
     138    def _get_pages(self):
     139        return self.paginator.pages
     140    pages = property(_get_pages)
     141
     142    def _get_page_number(self):
     143        return self.base + self._page_number
     144    page_number = property(_get_page_number)
     145
     146    def _get_next_page_number(self):
     147        if self.has_next_page():
     148            # Uses page_number so that we return the correct base
     149            return self.page_number + 1
     150    next_page_number = property(_get_next_page_number)
     151
     152    def _get_previous_page_number(self):
     153        if self.has_previous_page():
     154            # Uses page_number so that we return the correct base
     155            return self.page_number - 1
     156    previous_page_number = property(_get_previous_page_number)
  • django/views/generic/list_detail.py

    === modified file 'django/views/generic/list_detail.py'
     
    11from django.template import loader, RequestContext
    22from django.http import Http404, HttpResponse
    33from django.core.xheaders import populate_xheaders
    4 from django.core.paginator import ObjectPaginator, InvalidPage
     4from django.core.paginator import ObjectPaginatorForPage, InvalidPage
    55from django.core.exceptions import ObjectDoesNotExist
    66
    77def object_list(request, queryset, paginate_by=None, page=None,
     
    1717            list of objects
    1818        is_paginated
    1919            are the results paginated?
    20         results_per_page
    21             number of objects per page (if paginated)
    22         has_next
    23             is there a next page?
    24         has_previous
    25             is there a prev page?
    26         page
    27             the current page
    28         next
    29             the next page
    30         previous
    31             the previous page
    32         pages
    33             number of pages, total
    34         hits
    35             number of objects, total
    36         last_on_page
    37             the result number of the last of object in the
    38             object_list (1-indexed)
    39         first_on_page
    40             the result number of the first object in the
    41             object_list (1-indexed)
     20        paginator
     21            paginator object used to navigate the list (if paginated)
    4222    """
    4323    if extra_context is None: extra_context = {}
    4424    queryset = queryset._clone()
    4525    if paginate_by:
    46         paginator = ObjectPaginator(queryset, paginate_by)
    4726        if not page:
    4827            page = request.GET.get('page', 1)
    4928        try:
    5029            page = int(page)
    51             object_list = paginator.get_page(page - 1)
     30            paginator = ObjectPaginatorForPage(queryset, paginate_by, page_number=page - 1)
     31            object_list = paginator.get_page()
    5232        except (InvalidPage, ValueError):
    5333            if page == 1 and allow_empty:
    5434                object_list = []
     35                paginator = None
    5536            else:
    5637                raise Http404
    5738        c = RequestContext(request, {
    5839            '%s_list' % template_object_name: object_list,
    59             'is_paginated': paginator.pages > 1,
    60             'results_per_page': paginate_by,
    61             'has_next': paginator.has_next_page(page - 1),
    62             'has_previous': paginator.has_previous_page(page - 1),
    63             'page': page,
    64             'next': page + 1,
    65             'previous': page - 1,
    66             'last_on_page': paginator.last_on_page(page - 1),
    67             'first_on_page': paginator.first_on_page(page - 1),
    68             'pages': paginator.pages,
    69             'hits' : paginator.hits,
     40            'is_paginated': paginator and paginator.pages > 1 or False,
    7041        }, context_processors)
     42        if paginator is not None:
     43            c['paginator'] = paginator
    7144    else:
    7245        c = RequestContext(request, {
    7346            '%s_list' % template_object_name: queryset,
Back to Top