2

I'm building a site like reddit. Objects are sorted by rating. I was hoping that someone could help me implement pagination. I just want to first load the top 20 objects. Then on click of a "next" button, i want the next 20 objects to load based on the 20th object's rating. Here are the google docs: https://developers.google.com/appengine/docs/python/datastore/queries?hl=en .

Does anyone know of a way to do this? Or is there a good tutorial out there?

tjones
  • 357
  • 2
  • 6
  • 23

2 Answers2

2

This is a generic function that I am using in order to retrieve my model instances along with the cursor. The function takes parameters, which I am reading them from the request.

def retrieve_dbs(query, order=None, limit=None, cursor=None, **filters):
  ''' Retrieves entities from datastore, by applying cursor pagination
  and equality filters. Returns dbs and more cursor value
  '''
  limit = limit or config.DEFAULT_DB_LIMIT
  cursor = Cursor.from_websafe_string(cursor) if cursor else None
  model_class = ndb.Model._kind_map[query.kind]
  if order:
    for o in order.split(','):
      if o.startswith('-'):
        query = query.order(-model_class._properties[o[1:]])
      else:
        query = query.order(model_class._properties[o])

  for prop in filters:
    if filters.get(prop, None) is None:
      continue
    if type(filters[prop]) == list:
      for value in filters[prop]:
        query = query.filter(model_class._properties[prop] == value)
    else:
      query = query.filter(model_class._properties[prop] == filters[prop])

  model_dbs, more_cursor, more = query.fetch_page(limit, start_cursor=cursor)
  more_cursor = more_cursor.to_websafe_string() if more else None
  return list(model_dbs), more_cursor

You can call it in that fashion. I am using the extentions entity_db and entity_dbs to signify that my variables refer to an entity object, *_db and *_dbs define if there are one or many results.

entity_dbs, entity_cursor = retrieve_dbs(
    model.Entity.query(),
    limit=limit,  # Your limit parameter
    cursor=cursor,  # The cursor if you want to grab a batch of next results
    order=order,
  )
topless
  • 8,069
  • 11
  • 57
  • 86
1

This is pretty straightforward if you use limit=20 in your datastore queries, and get a cursor afterwards to get the next 20.

dragonx
  • 14,963
  • 27
  • 44
  • How do I "get a cursor afterwards"? I saw this answer:http://stackoverflow.com/questions/4840731/how-to-use-cursor-for-pagination?rq=1 but i'm not sure what is happening. – tjones Apr 05 '13 at 00:24
  • 1
    after you call query.get(), call query.cursor() to get the cursor. When you issue the next query when clicking on the Next button, pass in the cursor on the next query. See the docs: https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_run – dragonx Apr 05 '13 at 01:16