How to flip to previous page with ndb cursors?

app-engine-ndb, database-cursor, google-app-engine, paging, python

Solution

So what I do here is use the current bookmark to for navigating for next or previous and removed the other query so it doesn't query twice for each request. (Edited the old description/answer was wrong when I tested it. This one works on my localhost).

Try:

is_prev = self.request.get('prev', False)
if is_prev:
    qry = q_reverse
    cursor = cursor.reversed()
else:
    qry = q_forward

feedbacks, cursor, more = qry.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=cursor)

if is_prev:
    prev_bookmark = cursor.reversed().urlsafe() if more else None
    next_bookmark = bookmark
else:
    prev_bookmark = bookmark
    next_bookmark = cursor.urlsafe() if more else None

html

{% if prev_bookmark %}
    <a href="{{ url_for(request.endpoint, bookmark=prev_bookmark, prev=True) }}">Previous</a>
{% endif %}
{% if next_bookmark %}
  <a href="{{ url_for(request.endpoint, bookmark=next_bookmark) }}">Next</a>
{% endif %}

Problem

I cant manage to get to 'previous page' in ndb paging. I have checked the documentation and also this similar question here without success. ``` def show_feedback(kind, bookmark=None): """Renders returned feedback.""" cursor = None more_p= None if bookmark: cursor = Cursor(urlsafe=bookmark) q = Feedback.query() q_forward = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(-Feedback.pub_date) q_reverse = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(Feedback.pub_date) feedbacks, next_cursor, more = q_forward.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=cursor) if cursor: rev_cursor = cursor.reversed() feedbacks2, prev_cursor, more_p = q_reverse.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=rev_cursor) next_bookmark = None prev_bookmark = None if more and next_cursor: next_bookmark = next_cursor.urlsafe() if more_p and prev_cursor: prev_bookmark = prev_cursor.urlsafe() return render_template_f11('show_feedback.html', kind=kind, feedbacks=feedbacks, next_bookmark=next_bookmark, prev_bookmark=prev_bookmark) ``` html: ``` {% if prev_bookmark %} <a href="{{ url_for(request.endpoint, bookmark=prev_bookmark) }}">Previous</a> {% endif %} {% if next_bookmark %} <a href="{{ url_for(request.endpoint, bookmark=next_bookmark) }}">Next</a> {% endif %} ``` I can page forwards correctly until the end. But I can't page backwards until the last page and even then I can't page back until the first page neither. What am I missing please? UPDATE: Changed code with Faisal's suggestions. It works better I must admit. But still the paging doesn't work correctly: I have 7 entries. PAGE_SIZE in config is 3. Hence we get three pages: When clicking on Next I get 7,6,5 -> 4,3,2 -> 1 Perfect. Now when clicking on previous: 1 -> 3,4,5 (?) -> 5,6,7 (?) Thanks for your help ``` def show_feedback(kind, bookmark=None): """Renders returned feedback.""" is_prev = request.args.get('prev', False) cursor = None if bookmark: cursor = Cursor(urlsafe=bookmark) q = Feedback.query() q_forward = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(-Feedback.pub_date) q_reverse = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(Feedback.pub_date) qry = q_reverse if is_prev else q_forward feedbacks, cursor, more = qry.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=cursor) if is_prev: prev_bookmark = cursor.reversed().urlsafe() if more else None next_bookmark = bookmark else: prev_bookmark = bookmark next_bookmark = cursor.urlsafe() if more else None return render_template_f11('show_feedback.html', kind=kind, feedbacks=feedbacks, next_bookmark=next_bookmark, prev_bookmark=prev_bookmark) ``` UPDATE 2: It seems now its nearly working with reverse(). 7,6,5 -> next -> 4,3,2 -> next -> 1 1 -> prev -> 2,3,4 -> 5,6,7 (Order is no longr latest date first)

Original source

Related problems