I just started using this class in my blog software.  It requires two
queries, one to get the main page of results plus the index of the
next page and one to get the index of the previous page.  Since it
requires two queries per request, you definitely want to use memcache
to save the results.  It works well with non-consecutive index
numbers, but it does only provide Next and Previous pages; it doesn't
provide for directly indexing page N.

I'd love to hear any thoughts on this approach and feedback, and
please feel free to use to code in your own app.

#Copyright 2008 Adam A. Crossland
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
#http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
#See the License for the specific language governing permissions and
#limitations under the License.

from google.appengine.ext import db
import copy

class PaginatedList(list):
    def __init__(self, *args, **kw):
        list.__init__(self, *args, **kw)
        self.prev_index = None
        self.next_index = None
        self.curr_index = None

class Paginator:
    "A class that supports pagination of AppEngine Models"
    def __init__(self, page_size, index_field):
        self.page_size = page_size
        self.index_field = index_field

    def get_page(self, query=None, start_index=None, ascending=True):
        "Takes a normal AppEngine Query and returns paginated
results."

        fetched = None

        # I need to make a copy of the query, as once I use it to get
the main
        # collection of desired records, I will not be able to re-use
it to get
        # the next or prev collection.
        query_copy = copy.deepcopy(query)

        if ascending:
            # First, I will grab the requested page of entities and
determine
            # the index for the next page
            filter_on = self.index_field + " >="
            fetched = PaginatedList(query.filter(filter_on,
start_index).order(self.index_field).fetch(self.page_size + 1))
            if len(fetched) > 0:
                # The first row that we get back is the real index.
                fetched.curr_index = fetched[0].index
            if len(fetched) > self.page_size:
                fetched.next_index = fetched[-1].index
                del(fetched[-1])
            # Now, I will try to determine the index of the previous
page
            filter_on = self.index_field + " <"
            previous_page = query_copy.filter(filter_on,
start_index).order("-" + self.index_field).fetch(self.page_size)
            if len(previous_page) > 0:
                fetched.prev_index = previous_page[-1].index
        else:
            # Follow the same logical pattern as for ascending, but
reverse
            # the polarity of the neutron flow
            filter_on = self.index_field + " <="
            fetched = PaginatedList(query.filter(filter_on,
start_index).order("-" + self.index_field).fetch(self.page_size + 1))
            if len(fetched) > 0:
                # The first row that we get back is the real index.
                fetched.curr_index = fetched[0].index
            if len(fetched) > self.page_size:
                fetched.next_index = fetched[-1].index
                del(fetched[-1])
            # Determine index of previous page
            filter_on = self.index_field + " >"
            previous_page = query_copy.filter(filter_on,
start_index).order(self.index_field).fetch(self.page_size)
            if len(previous_page) > 0:
                fetched.prev_index = previous_page[-1].index

        return fetched

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to google-appengine@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to