Contents

Usage

MongoFrames was initially developed for use in web applications (since that's what I do to pay the bills) so pagination support was an early requirement. To select a paginated set of results we use the Paginator class:

from mongoframes import *

class Dragon(Frame):

    _fields = {
        'name',
        'breed'
        }

# Select all dragons (paginated)
pages = Paginator(Dragon)

# Print the name of each dragon on the first page
for dragon in pages[1]:
    print(dragon.name)

Paginator requires a Frame class as the first argument (in this case we've specified Dragon) which it uses when requesting documents from the database. To access a page of results we simply index the Paginator instance (e.g pages) with a page number.

Pages are indexed from base 1 not 0.

The Paginator class accepts a filter argument along with any other query options that Frame.many accepts (e.g sort and projection) with the exception of skip and limit which are used internally.

This time we'll select only dragons that are fire or cold-drakes, sort them by breed then name and limit the fields returned to just name and breed (and _id but only because this is included by default and must be explicitly excluded).

pages = Paginator(
    Dragon,
    filter=In(Q.breed, ['Cold-drake', 'Fire-drake']),
    sort=[('breed', ASC), ('name', ASC)],
    projection={'name': True, 'breed': True}
    )

... do something with the results ...

We can also configure the items per page using the per_page and orphans options. Suppose we have 32 dragons in total, the default number of items returned per page is 20 but we change this to 10 and count the number of pages if all dragons are selected:

pages = Paginator(Dragon, per_page=10)
print(pages.page_count)

>> 4

At this point the page count is four with the last page containing just two dragons. Using the orphans option we can allow the last page to accept additional results, for example:

pages = Paginator(Dragon, per_page=10, orphans=2)
print(pages.page_count)

>> 3

Setting the orphans option to two allows the last page to contain 12 dragons and reduces the page count to three.

Removing the extra next page click for a measly two dragons is just plain good manners :)

Reference

Paginator

paginator = Paginator(
    frame_cls,
    filter,
    per_page,
    orphans,
    **filter_args
    )

A pagination class for slicing results into pages.

The filter argument is optional and if not provided all documents for the given frame_cls will be retrieved. The results per_page defaults to 20 and the number of orphans defaults to 0.

Paginator instances support iteration, for example:

# Print the number of each page
for page in paginator:
    print(page.number)

# Print the name of the first dragon on the first page
print(paginator[1].item[0].name)

When iterating over a Paginator instance or accessing a page by number, the paginator will query the database, there is no caching for subsequent page access. If you need to access the same page of results multiple times then consider storing a reference to the page and using it for subsequent operations.

paginator.item_count

(Read-only) The total number of items for the given collection and filter.

paginator.orphans

(Read-only) The number of orphaned results accepted by the last page.

paginator.page_count

(Read-only) The total number of pages.

paginator.page_numbers

(Read-only) A list of page numbers.

paginator.per_page

(Read-only) The number of results per page (with the exception of orphans).

Page

page = Page(offset, number, items, next, prev)

A class representing one page of results. Page instances support iteration, for example:

# Print the name of all dragons for all pages
for page in paginator:
    for dragon in page:
        print(dragon.name)

# Print the name of the first dragon on the first page
print(paginator[1].item[0].name)

Pages are generated by a Paginator and not typically created by external code.

page.items

(Read-only) A list of documents on the page.

page.next

(Read-only) The page number for the next page or None if there isn't one.

page.number

(Read-only) The page number.

page.prev

(Read-only) The page number for the previous page or None if there isn't one.

page.offset(item)

Return the offset for an item in the page. If the item is not in the page items a ValueError will be raised.