作者 一个GAE Python上的Paginator
Chris1919
2009-04-12 12:46
import urllib

#get query object, with or without filters
def build_query(cls, filters=None):
    query = cls.all()
    
    if filters is not None:
      for filter in filters:
        filter(query)

    return query

class BasePaginator(object):
    def __init__(self, request, query, num_per_page, page_qs='page'):
        self.request = request
        self.query = query
        self.num_per_page = num_per_page
        self.page_qs = page_qs
    
    def change_query_str(self, name, value):
        get = self.request.GET.copy()
        get[name] = str(value)
        query_str = urllib.urlencode(get) 
        return self.request.path + '?' + query_str

    def get_page_offset(self):
        try:
            page = int(self.request.GET.get(self.page_qs, 1))
            if page < 1:
                page = 1
        except:
            page = 1
          
        offset = page - 1
        return (page, offset)

    #do pagination
    def get_page_info(self, next=False):
        page_num, offset = self.get_page_offset()
        page = {}
        page['prev'] = page['next'] = False
    
        if offset > 0:
            page['prev'] = True
            page['prev_page'] = page_num - 1
            page['prev_page_url'] = self.change_query_str(self.page_qs, page['prev_page'])
        if next == True:
            page['next'] = True
            page['next_page'] = page_num + 1
            page['next_page_url'] = self.change_query_str(self.page_qs, page['next_page'])
    
        return page

    def get_page_objects(self):
        page_num, offset = self.get_page_offset()
        objects = self.query.fetch(self.num_per_page+1, self.num_per_page*offset)
        #pagination info
        page = self.get_page_info(len(objects) > self.num_per_page)
        objects = objects[0:self.num_per_page]
        return (objects, page)
    
class Paginator(BasePaginator):
    def __init__(self, request, model, filters=[], num_per_page=10, page_qs='page'):
        query = build_query(cls=model, filters=filters)
        BasePaginator.__init__(self, request, query, num_per_page, page_qs)
上面的request是一个Django request。如何使用:
objs, page = Paginator(request, ModelA).get_page_objects()
objs就是给ModelA分页出来的对象list。page则包括分页信息,包括是否有上一页、下一页,自动生成的上一页和下一页的URL。如果要加一些过滤条件,就输入一个filters参数:
filters = []
filters.append(lambda q: q.filter('xxx =', yyy))
objs, page = Paginator(request, ModelA, filters).get_page_objects()
这样就可以给所有满足xxx==yyy的数据进行分页。
Bookmark and Share