paginate – Paging and pagination

webhelpers.paginate

webhelpers.paginate.get_wrapper(obj, sqlalchemy_session=None)

Auto-detect the kind of object and return a list/tuple to access items from the collection.

class webhelpers.paginate.Page(collection, page=1, items_per_page=20, item_count=None, sqlalchemy_session=None, presliced_list=False, url=None, **kwargs)

A list/iterator of items representing one page in a larger collection.

An instance of the “Page” class is created from a collection of things. The instance works as an iterator running from the first item to the last item on the given page. The collection can be:

  • a sequence
  • an SQLAlchemy query - e.g.: Session.query(MyModel)
  • an SQLAlchemy select - e.g.: sqlalchemy.select([my_table])

A “Page” instance maintains pagination logic associated with each page, where it begins, what the first/last item on the page is, etc. The pager() method creates a link list allowing the user to go to other pages.

WARNING: Unless you pass in an item_count, a count will be performed on the collection every time a Page instance is created. If using an ORM, it’s advised to pass in the number of items in the collection if that number is known.

Instance attributes:

original_collection
Points to the collection object being paged through
item_count
Number of items in the collection
page
Number of the current page
items_per_page
Maximal number of items displayed on a page
first_page
Number of the first page - starts with 1
last_page
Number of the last page
page_count
Number of pages
items
Sequence/iterator of items on the current page
first_item
Index of first item on the current page - starts with 1
last_item
Index of last item on the current page
pager(format='~2~', page_param='page', partial_param='partial', show_if_single_page=False, separator=' ', onclick=None, symbol_first='<<', symbol_last='>>', symbol_previous='<', symbol_next='>', link_attr={'class': 'pager_link'}, curpage_attr={'class': 'pager_curpage'}, dotdot_attr={'class': 'pager_dotdot'}, **kwargs)

Return string with links to other pages (e.g. “1 2 [3] 4 5 6 7”).

format:

Format string that defines how the pager is rendered. The string can contain the following $-tokens that are substituted by the string.Template module:

  • $first_page: number of first reachable page
  • $last_page: number of last reachable page
  • $page: number of currently selected page
  • $page_count: number of reachable pages
  • $items_per_page: maximal number of items per page
  • $first_item: index of first item on the current page
  • $last_item: index of last item on the current page
  • $item_count: total number of items
  • $link_first: link to first page (unless this is first page)
  • $link_last: link to last page (unless this is last page)
  • $link_previous: link to previous page (unless this is first page)
  • $link_next: link to next page (unless this is last page)

To render a range of pages the token ‘~3~’ can be used. The number sets the radius of pages around the current page. Example for a range with radius 3:

‘1 .. 5 6 7 [8] 9 10 11 .. 500’

Default: ‘~2~’

symbol_first

String to be displayed as the text for the %(link_first)s link above.

Default: ‘<<’

symbol_last

String to be displayed as the text for the %(link_last)s link above.

Default: ‘>>’

symbol_previous

String to be displayed as the text for the %(link_previous)s link above.

Default: ‘<’

symbol_next

String to be displayed as the text for the %(link_next)s link above.

Default: ‘>’

separator:

String that is used to separate page links/numbers in the above range of pages.

Default: ‘ ‘

page_param:

The name of the parameter that will carry the number of the page the user just clicked on. The parameter will be passed to a url_for() call so if you stay with the default ‘:controller/:action/:id’ routing and set page_param=’id’ then the :id part of the URL will be changed. If you set page_param=’page’ then url_for() will make it an extra parameters like ‘:controller/:action/:id?page=1’. You need the page_param in your action to determine the page number the user wants to see. If you do not specify anything else the default will be a parameter called ‘page’.

Note: If you set this argument and are using a URL generator callback, the callback must accept this name as an argument instead of ‘page’. callback, becaust the callback requires its argument to be ‘page’. Instead the callback itself can return any URL necessary.

partial_param:

When using AJAX/AJAH to do partial updates of the page area the application has to know whether a partial update (only the area to be replaced) or a full update (reloading the whole page) is required. So this parameter is the name of the URL parameter that gets set to 1 if the ‘onclick’ parameter is used. So if the user requests a new page through a Javascript action (onclick) then this parameter gets set and the application is supposed to return a partial content. And without Javascript this parameter is not set. The application thus has to check for the existence of this parameter to determine whether only a partial or a full page needs to be returned. See also the examples in this modules docstring.

Default: ‘partial’

Note: If you set this argument and are using a URL generator callback, the callback must accept this name as an argument instead of ‘partial’.

show_if_single_page:

if True the navigator will be shown even if there is only one page

Default: False

link_attr (optional)

A dictionary of attributes that get added to A-HREF links pointing to other pages. Can be used to define a CSS style or class to customize the look of links.

Example: { ‘style’:’border: 1px solid green’ }

Default: { ‘class’:’pager_link’ }

curpage_attr (optional)

A dictionary of attributes that get added to the current page number in the pager (which is obviously not a link). If this dictionary is not empty then the elements will be wrapped in a SPAN tag with the given attributes.

Example: { ‘style’:’border: 3px solid blue’ }

Default: { ‘class’:’pager_curpage’ }

dotdot_attr (optional)

A dictionary of attributes that get added to the ‘..’ string in the pager (which is obviously not a link). If this dictionary is not empty then the elements will be wrapped in a SPAN tag with the given attributes.

Example: { ‘style’:’color: #808080’ }

Default: { ‘class’:’pager_dotdot’ }

onclick (optional)

This paramter is a string containing optional Javascript code that will be used as the ‘onclick’ action of each pager link. It can be used to enhance your pager with AJAX actions loading another page into a DOM object.

In this string the variable ‘$partial_url’ will be replaced by the URL linking to the desired page with an added ‘partial=1’ parameter (or whatever you set ‘partial_param’ to). In addition the ‘$page’ variable gets replaced by the respective page number.

Note that the URL to the destination page contains a ‘partial_param’ parameter so that you can distinguish between AJAX requests (just refreshing the paginated area of your page) and full requests (loading the whole new page).

[Backward compatibility: you can use ‘%s’ instead of ‘$partial_url’]

jQuery example:
“$(‘#my-page-area’).load(‘$partial_url’); return false;”
Yahoo UI example:
“YAHOO.util.Connect.asyncRequest(‘GET’,’$partial_url’,{
success:function(o){YAHOO.util.Dom.get(‘#my-page-area’).innerHTML=o.responseText;} },null); return false;”
scriptaculous example:
“new Ajax.Updater(‘#my-page-area’, ‘$partial_url’,
{asynchronous:true, evalScripts:true}); return false;”
ExtJS example:
“Ext.get(‘#my-page-area’).load({url:’$partial_url’}); return false;”
Custom example:
“my_load_page($page)”

Additional keyword arguments are used as arguments in the links. Otherwise the link will be created with url_for() which points to the page you are currently displaying.

Temporary understudy for examples:

The unit tests are often educational ...

""""Test webhelpers.paginate package."""

from routes import Mapper

from webhelpers.paginate import Page


def test_empty_list():
    """Test whether an empty list is handled correctly."""
    items = []
    page = Page(items, page=0)
    assert page.page == 0
    assert page.first_item is None
    assert page.last_item is None
    assert page.first_page is None
    assert page.last_page is None
    assert page.previous_page is None
    assert page.next_page is None
    assert page.items_per_page == 20
    assert page.item_count == 0
    assert page.page_count == 0
    assert page.pager() == ''
    assert page.pager(show_if_single_page=True) == ''

def test_one_page():
    """Test that we fit 10 items on a single 10-item page."""
    items = range(10)
    page = Page(items, page=0, items_per_page=10)
    assert page.page == 1
    assert page.first_item == 1
    assert page.last_item == 10
    assert page.first_page == 1
    assert page.last_page == 1
    assert page.previous_page is None
    assert page.next_page is None
    assert page.items_per_page == 10
    assert page.item_count == 10
    assert page.page_count == 1
    assert page.pager() == ''
    assert page.pager(show_if_single_page=True) == \
        '<span class="pager_curpage">1</span>'

def test_many_pages():
    """Test that 100 items fit on seven 15-item pages."""
    # Create routes mapper so that webhelper can create URLs
    # using webhelpers.url_for()
    mapper = Mapper()
    mapper.connect(':controller')

    items = range(100)
    page = Page(items, page=0, items_per_page=15)
    assert page.page == 1
    assert page.first_item == 1
    assert page.last_item == 15
    assert page.first_page == 1
    assert page.last_page == 7
    assert page.previous_page is None
    assert page.next_page == 2
    assert page.items_per_page == 15
    assert page.item_count == 100
    assert page.page_count == 7
    print page.pager()
    assert page.pager() == \
        '<span class="pager_curpage">1</span> ' + \
        '<a class="pager_link" href="/content?page=2">2</a> ' + \
        '<a class="pager_link" href="/content?page=3">3</a> ' + \
        '<span class="pager_dotdot">..</span> ' + \
        '<a class="pager_link" href="/content?page=7">7</a>'
    assert page.pager(separator='_') == \
        '<span class="pager_curpage">1</span>_' + \
        '<a class="pager_link" href="/content?page=2">2</a>_' + \
        '<a class="pager_link" href="/content?page=3">3</a>_' + \
        '<span class="pager_dotdot">..</span>_' + \
        '<a class="pager_link" href="/content?page=7">7</a>'
    assert page.pager(page_param='xy') == \
        '<span class="pager_curpage">1</span> ' + \
        '<a class="pager_link" href="/content?xy=2">2</a> ' + \
        '<a class="pager_link" href="/content?xy=3">3</a> ' + \
        '<span class="pager_dotdot">..</span> ' + \
        '<a class="pager_link" href="/content?xy=7">7</a>'
    assert page.pager(
        link_attr={'style':'s1'},
        curpage_attr={'style':'s2'},
        dotdot_attr={'style':'s3'}) == \
            '<span style="s2">1</span> ' + \
            '<a href="/content?page=2" style="s1">2</a> ' + \
            '<a href="/content?page=3" style="s1">3</a> ' + \
            '<span style="s3">..</span> ' + \
            '<a href="/content?page=7" style="s1">7</a>'

Project Versions

Table Of Contents

Previous topic

number – Numbers and statistics helpers

Next topic

webhelpers.pylonslibflash alert div helpers

This Page