Search code examples
pythongoogle-app-enginegoogle-cloud-datastore

App Engine datastore paging - previous page


I'm trying to create a paging mechanism to page through a query. Going forward is not an issue. Going to a previous page seems to be non-trivial though.

What I have so far is this (why do I have the feeling that it should be simpler?):

cursor_urlsafe = self.request.get('cursor', None)
rev = bool(self.request.get('rev', None))
cursor = ndb.Cursor(urlsafe=cursor_urlsafe)
if rev:
    next_query = Shot.query(Shot.schedule_key == schedule.key).order(Shot.date_created)
    cursor = cursor.reversed()
else:
    next_query = Shot.query(Shot.schedule_key == schedule.key).order(-Shot.date_created)

shots, next_cursor, more = next_query.fetch_page(PAGE_LENGTH, start_cursor=cursor)

if rev:
    shots.sort(key=lambda x: -x.date_created_epoch)

next_cursor_url_safe = next_cursor.urlsafe() if next_cursor else None
template_params = {
    'shots': shots,
    'next_cursor': next_cursor_url_safe,
    'prev_cursor': next_cursor_url_safe if cursor_urlsafe else None
}

and on the client side:

<a href="/schedule/{{ s.id }}?cursor={{ prev_cursor }}&rev=true">Previous</a><br>
<a href="/schedule/{{ s.id }}?cursor={{ next_cursor }}">Next</a>

This sort of works. The only problem is that when the user "changes direction" (pages back) it brings him to the page he is on again, and only after another click on previous it goes to the previous page.

So if click, Previous and then Next I remain on the same page all the time.

Please advise.


Solution

  • There are a few strategies you can adopt. Storing previous cursors - See https://p.ota.to/blog/2013/4/pagination-with-cursors-in-the-app-engine-datastore/ or alternately search SO for another approach What is the correct way to get the previous page of results given an NDB cursor?