Module Contents



This module provides efficient pagination for a small specified set of queries.

class core.pagination.Pagination(page_size: int = 10, max_pages: int = 100)

This module provides efficient pagination for a small specified set of queries. The datastore does not provide an efficient method for skipping N number of entities. This prevents the usual navigation over multiple pages (in most cases - like a google search - the user expects a list of pages (e.g. 1-10) on the bottom of each page with direct access to these pages). With the datastore and it’s cursors, the most we can provide is a next-page & previous-page link using cursors. This module provides an efficient method to provide these direct-access page links under the condition that only a few, known-in-advance queries will be run. This is typically the case for forums, where there is only one query per thread (it’s posts ordered by creation date) and one for the threadlist (it’s threads, ordered by changedate).

To use this module, create an instance of this index-manager on class-level (setting page_size & max_pages). Then call :meth:get_pages with the query you want to retrieve the cursors for the individual pages for. This will return one start-cursor per available page that can then be used to create urls that point to the specific page. When the entities returned by the query change (eg a new post is added), call :meth:refresh_index for each affected query.


The refreshAll Method is missing - intentionally. Whenever data changes you have to call refresh_index for each affected Index. As long as you can name them, their number is limited and this module can be efficiently used.

_db_type = 'viur_pagination'
key_from_query(query: viur.core.db.Query) str

Derives a unique Database-Key from a given query. This Key is stable regardless in which order the filter have been applied


query – Query to derive key from


The unique key derived

get_or_build_index(orig_query: viur.core.db.Query) List[str]

Builds a specific index based on origQuery AND local variables (self.page_size and self.max_pages) Returns a list of starting-cursors for each page. You probably shouldn’t call this directly. Use cursor_for_query.


orig_query – Query to build the index for

cursor_for_query(query: viur.core.db.Query, page: int) str | None

Returns the starting-cursor for the given query and page using an index.

  • query – Query to get the cursor for

  • page – Page the user wants to retrieve


Cursor or None if no cursor is applicable

get_pages(query: viur.core.db.Query) List[str]

Returns a list of all starting-cursors for this query. The first element is always None as the first page doesn’t have any start-cursor

refresh_index(query: viur.core.db.Query) None

Refreshes the Index for the given query (Actually it removes it from the db, so it gets rebuild on next use)


query – Query for which the index should be refreshed