django-pagination-plus
This template tag library is used for displaying pagination links in paginated
Django views. It exposes a template tag {% paginationplus %}
that will take
care of iterating over the page numbers.
Usage
Add paginationplus
to your INSTALLED_APPS
in your settings.
At the start of the template for your paginated view, use the following to load the tag module:
{% load paginationplus %}
Then, at the position you want your pagination links to appear, use the following block tag.
{% paginationplus page_obj url_name url_arg1=... url_arg2=... %} ... {% endpaginationplus %}
The first argument passed to the opening tag is the Page
object of your
paginated view. The remaining arguments are the same as the arguments passed to
the built-in {% url %}
tag, minus the argument that takes the value for the
page number in the view, eg. page
in the generic view ListView
.
The block iterates over the page numbers available from the Paginator
object
associated with the Page
object that is passed as the first argument to the
opening tag.
The block's content is rendered once for each iteration, and within this block,
a template variable named paginationplus
is available.
This template variable exposes four attributes:
-
number
The page number that is the subject of this iteration -
url
Contains the url of the page for the page number currently iterated over. -
is_filler
When this is True, the current iteration does not represent a page number, but instead represents a filler, ie. a hole in the sequence of page numbers. See below for more information. -
is_current
When this is True, the current iteration represents number of the page that is currently displayed in the view.
Single tag usage
An alternative to the block tag, is the following:
{% paginationplus page_obj url_name url_arg1=... url_arg2=... ... with 'template/name.html' %}
Using with
in the tag indicates that the iteration will not occur in a
block, but instead in the template that follows with
. Within this template,
the parent template's full context is available, with an added
paginationplus
variable. The template passed to the tag needn't be a string,
any available template variable will do.
Settings
By default, paginationplus will support displaying the links for the first,
previous, current, next, and last page. For instance, if you have a paginated
view with 99 pages, and the current page is page 30, the following sequence will
be iterated over: [1, None, 29, 30, 31, None, 99]
. Suppose the current page
is page 3, the sequence will be [1, 2, 3, 4, None, 99]
.
In the above sequences, the None
values represent a hole in the page number
sequence, and for these holes, the paginationplus
template variable will
have its is_filler
attribute set to True
, the number
and url
attributes will be set to None
, and is_current
will be set to False
.
To disable this behavior, and iterate over all available page numbers, you can
set the PAGINATIONPLUS_CONTIGUOUS
setting to True
in your project's
settings.
To control the number of page numbers before and after the current page that
will be iterated over, you can set the PAGINATIONPLUS_MAX_DISTANCE
option.
For instance, when PAGINATIONPLUS_MAX_DISTANCE
is set to 2, the following
sequence will be iterated over when the number of pages is 99 and the current
page is 30: [1, None, 28, 29, 30, 31, 32, None, 99]
. And when the current
page is 3, the sequence will be [1, 2, 3, 4, 5, None, 99]
.
Example
Suppose you use a generic ListView
in your application that exposes a list
of objects of the Item
model. Let's have a look at a possible urlconf:
# urls.py from django.conf.urls import patterns, url from django.views.generic import ListView from exampleapp import models urlpatterns = patterns('', # ... url(r'^items/(?:page/(?P<page>\d+)/)?$', ListView.as_view( model=models.Item, template_name='items.html', paginate_by=5 ), name='show_my_items'), )
The part that displays the items in the items.html
template could then look
like this:
{# items.html #} {# ... stuff ... #} <ul class="items"> {% for item in object_list %} <li>{{item}}</li> {# or something else to display the item #} {% endfor %} </ul> <ul class="pagination"> {% paginationplus page_obj show_my_items %} {% if paginationplus.is_filler %} <li>…</li> {% else %} <li class="{% if paginationplus.is_current %}current{% endif %}"> <a href="{{paginationplus.url}}">{{paginationplus.number}}</a> </li> {% endif %} {% endpaginationplus %} </ul> {# ... stuff ... #}
When this view is visited by a user, the HTML will look something like this:
<ul class="items"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> <li>Item 5</li> </ul> <ul class="pagination"> <li class="current"> <a href="/items/page/1/">1</a> </li> <li class=""> <a href="/items/page/2/">2</a> </li> <li>…</li> <li class=""> <a href="/items/page/20/">20</a> </li> </ul>
Another possibility for displaying a page link is to use the following in the
template instead of the <a>
tag and its contents:
{{paginationplus}}
This will output an anchor tag containing the page number, with its href attribute set to the page's URL.