Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django pagination...slicing pages to show fraction of total pages?

I have the pagination module working for the most part but there's one issue. How can I only show a slice of the total available pages. For example, let's say I'm on page 5 of n pages, I'd want to show.

1,2,3,4,5,6....(n-1)(n).

I believe that Ruby has some fancy front-end magic to accomplish this. Is there anything that I can do within the django module?

From looking at other sites, it seems as though the logic basically goes, pick a fixed number of spots. If that number is larger than the amount currently display, add items when users page forward. Once that number of spots is reached, only show x spots to the left and right of the current page.

Should I just write my own template logic to accomplish that?

Thanks

like image 972
Ben Avatar asked Mar 24 '11 22:03

Ben


3 Answers

Quite a few nice articles about implementing what you are asking for in django. Lots of pluggable packages to customize if you don't want to roll your own.

http://www.tummy.com/Community/Articles/django-pagination/

https://github.com/dcramer/django-paging

Very well document snippet that wraps the built in paginator:

http://blog.elsdoerfer.name/2008/03/06/yet-another-paginator-digg-style/

  • http://djangosnippets.org/snippets/773/
like image 91
dting Avatar answered Nov 16 '22 21:11

dting


I just implemented this using the "Digg-like Paginator" from Django Snippets.

This is definitely what you are looking for.

Just dump that code into a Python module like digg_paginator.py and import it like so...

from django.core.paginator import InvalidPage, EmptyPage #, Paginator
from digg_paginator import DiggPaginator as Paginator

Then in my templates I had to switch from...

{% for page_num in page.paginator.page_range %}

to

{% for page_num in page.page_range %}

That's it! The DiggPaginator has the exact same interface as Django's built in one plus some features so you can just drop it into place and then adjust it with some customizations if you feel the need.

like image 7
Chris W. Avatar answered Nov 16 '22 20:11

Chris W.


I recently had to do the exact same thing for my site Wantbox.com and found a very simple and effective solution.

I add this snippet in my app's "templatetags" directory in a file called "paginator.py":

#  Based on: http://www.djangosnippets.org/snippets/73/
#
#  Modified by Sean Reifschneider to be smarter about surrounding page
#  link context.  For usage documentation see:
#
#     http://www.tummy.com/Community/Articles/django-pagination/

from django import template

register = template.Library()

def paginator(context, adjacent_pages=2):
    """
    To be used in conjunction with the object_list generic view.

    Adds pagination context variables for use in displaying first, adjacent and
    last page links in addition to those created by the object_list generic
    view.

    """
    startPage = max(context['page'] - adjacent_pages, 1)
    if startPage <= 3: startPage = 1
    endPage = context['page'] + adjacent_pages + 1
    if endPage >= context['pages'] - 1: endPage = context['pages'] + 1
    page_numbers = [n for n in range(startPage, endPage) \
            if n > 0 and n <= context['pages']]
    page_obj = context['page_obj']
    paginator = context['paginator']

    return {
        'page_obj': page_obj,
        'paginator': paginator,
        'hits': context['hits'],
        'results_per_page': context['results_per_page'],
        'page': context['page'],
        'pages': context['pages'],
        'page_numbers': page_numbers,
        'next': context['next'],
        'previous': context['previous'],
        'has_next': context['has_next'],
        'has_previous': context['has_previous'],
        'show_first': 1 not in page_numbers,
        'show_last': context['pages'] not in page_numbers,
    }

register.inclusion_tag('paginator.html', takes_context=True)(paginator)

Then I add this to the page where I want the pagination:

<div>{% if is_paginated %}{% load paginator %}{% paginator 3 %}{% endif %}</div>

Changing the "3" to "2" or "4" modifies how the pagination truncates. You can see an example on my site here (top right of the page).

like image 2
mitchf Avatar answered Nov 16 '22 20:11

mitchf