开发者

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

I have the pagination module working for 开发者_如何学Gothe 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


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/


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.


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).


If you are using ListView, here is your paginator function:

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_obj'].number - adjacent_pages, 1)
    if startPage <= 3: startPage = 1
    endPage = context['page_obj'].number + adjacent_pages + 1
    if endPage >= context['paginator'].num_pages - 1: endPage = context['paginator'].num_pages + 1
    page_numbers = [n for n in range(startPage, endPage) \
            if n > 0 and n <= context['paginator'].num_pages]
    page_obj = context['page_obj']
    paginator = context['paginator']

    return {
        'page_obj': page_obj,
        'paginator': paginator,
        'page': context['page_obj'].number,
        'pages': context['paginator'].num_pages,
        'page_numbers': page_numbers,
        'next': context['page_obj'].next_page_number,
        'previous': context['page_obj'].previous_page_number,
        'has_next': context['page_obj'].has_next,
        'has_previous': context['page_obj'].has_previous,
        'show_first': 1 not in page_numbers,
        'show_last': context['paginator'].num_pages not in page_numbers,
    }

My Template

    <nav>
        <ul class="pagination">
            <li{% if not page_obj.has_previous %} class="disabled"{% endif %}>
                <a {% if page_obj.has_previous %} href="?{{ path }}page={{ page_obj.previous_page_number }}"{% endif %}><i
                        class="fa fa-angle-left"></i></a>
            </li>
            {% if show_first %}
                <li><a href="?{{ path }}page=1">1</a></li>
                <li class="disabled"><a>&hellip;</a></li>
            {% endif %}
            {% for linkpage in page_numbers %}
                {% ifequal linkpage page %}
                    <li class="active"><a>{{ page }}</a></li>
                {% else %}
                    <li><a href="?{{ path }}page={{ linkpage }}">{{ linkpage }}</a></li>
                {% endifequal %}
            {% endfor %}
            {% if show_last %}
                <li class="disabled"><a>&hellip;</a></li>
                <li><a href="?{{ path }}page=last">{{ pages }}</a></li>
            {% endif %}
            <li{% if not page_obj.has_next %} class="disabled"{% endif %}>
                <a {% if page_obj.has_next %}  href="?{{ path }}page={{ page_obj.next_page_number }}"{% endif %}><i
                        class="fa fa-angle-right"></i></a>
            </li>
        </ul>
</nav>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜