python backward paging
Asked Answered
A

1

1

i have tried to make a backward paging, based on the example of google appengine documentation

NDB Query Cursor

my question is focused on this example:

# Set up.
q = Bar.query()
q_forward = q.order(Bar.key)
q_reverse = q.order(-Bar.key)

# Fetch a page going forward.
bars, cursor, more = q_forward.fetch_page(10)

# Fetch the same page going backward.
rev_cursor = cursor.reversed()
bars1, cursor1, more1 = q_reverse.fetch_page(10, start_cursor=rev_cursor)

based on this example i create my own version (like this):

def get(self):
        #testing = Testing(t="a");
        #testing.put();
        #testing2 = Testing(t="b");
        #testing2.put();
        #testing3 = Testing(t="c");
        #testing3.put();
        #testing4 = Testing(t="d");
        #testing4.put();
        #testing5 = Testing(t="e");
        #testing5.put();

        cursor = ndb.Cursor.from_websafe_string(self.request.get("c"))

        if cursor:
                q = Testing.query()
                q_forward = q.order(Testing.key)
                q_reverse = q.order(-Testing.key)

                bars, next_cursor, more = q_forward.fetch_page(2, start_cursor=cursor)
                rev_cursor = cursor.reversed()
                bars1, prev_cursor, more1 = q_reverse.fetch_page(2, start_cursor=rev_cursor)

                self.response.write("<a href=\"?c="+prev_cursor.to_websafe_string()+"\">&laquo</a><br />")
        else:
                q = Testing.query()
                q_forward = q.order(Testing.key)
                q_reverse = q.order(-Testing.key)

                bars, next_cursor, more = q_forward.fetch_page(2)

        self.response.write('Hello world!<br />')

        for bar in bars:
                self.response.write(bar.t + "<br />")


        self.response.write("<a href=\"?c="+next_cursor.to_websafe_string()+"\">&raquo</a>")

but i still not understand why, it cannot back to previous page perfectly... when i click forward page 1 to page 2:

Page 1 : a, b Page 2 : c, d

but when i click backward:

Page 2: c, d Page 1: b, c (should be: a, b)

it confused me a lot, since somebody at forum, can make it work based on this example, and nobody give an example code from them...

Agility answered 27/1, 2013 at 0:10 Comment(0)
A
2

The issue is that you are using c to refer to a backwards and forwards cursor.

So, when you get a backwards cursor which has already been reversed, you are calling

rev_cursor = cursor.reversed()

before

bars1, prev_cursor, more1 = q_reverse.fetch_page(2, start_cursor=rev_cursor)

and so the cursor begins pointing in the other direction before beginning the query.

To see a simpler test of this, define the same model and pre-populate some data:

from google.appengine.ext import ndb
class Testing(ndb.Model):
  t = ndb.StringProperty()
ndb.put_multi([Testing(t='a'), Testing(t='b'), Testing(t='c')])

get a cursor by querying for the first two elements:

>>> q_forward = Testing.query().order(Testing.t)
>>> result, forward_cursor, _ = q_forward.fetch_page(2)
>>> print [value.t for value in result]
[u'a', u'b']

use that cursor in a reverse query without reversing it

>>> reverse_cursor = forward_cursor.reversed()
>>> result, _, _ = q_reverse.fetch_page(2, start_cursor=reverse_cursor)
>>> print [value.t for value in result]
[u'b', u'a']

versus in a reverse query after doing so:

Adjoint answered 27/1, 2013 at 1:53 Comment(2)
I don't see where you defined the q_reverse query in for the simpler test. I am very interested, thank you.Percival
Ah, never mind, it's just q_reverse = Testing.query().order(-Testing.t). I actually want to page backwards and still see the order be ['a', 'b'].Percival

© 2022 - 2024 — McMap. All rights reserved.