如何对数据集进行分页
Posted
技术标签:
【中文标题】如何对数据集进行分页【英文标题】:How to page the dataset 【发布时间】:2011-10-02 07:56:54 【问题描述】:您好,我想启用曾经可以正常工作的网页分页,但它在更新环境或我的实施期间中断(不确定是哪个)。我想对 GAE 排序的列表进行分页 由于对象往往具有“自然顺序”,即时间、数字、单词等,此代码是否已经在可用的地方可用?我尝试做类似 Google 在此处列出的 Joey G 的示例:http://code.google.com/appengine/articles/paging.html 我从 URL 查询中获取名为书签的参数的努力:
next = None
bookmark = self.request.get("bookmark")
category = self.request.get('cg')#category parameter
if bookmark:
bookmark = datetime.strftime(bookmark[:-7], "%Y-%m-%d %H:%M:%S")
else:
bookmark = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
if cg:
articles = Articles.all().filter("category =", cg).filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
它曾经可以工作,现在分页已损坏,可能是因为我不完全了解如何处理修改后的日期时间对象。你能在路上帮我吗?我的用例的 URL 是 www.koolbusiness.com/li 谢谢
编辑/更新:这是显示列表页面的当前代码。它只在少数几个地方使用IN
,所以据说它可以在没有IN
的情况下被重写以工作,困难在于它分支太多,因为可能有许多组合,即搜索有或没有类别,有或没有搜索的类别和也是地理空间上的,但我不认为我在尝试一些不可能的事情,只是需要学习更多 python(涉及 lambda 编程,我只是粘贴并没有完全掌握)并在所有的时候获得更清晰的结构组合被处理。
class I18NListPage(FBBaseHandler,I18NHandler):
def get(self, cursor=None, limit=60, PAGESIZE = 10, twittername = None):
client = OAuthClient('twitter', self)
if client.get_cookie():
info = client.get('/account/verify_credentials')
twittername = info['screen_name']
if (users.is_current_user_admin()):
timeline = datetime.now () - timedelta (days = limit)
else:
timeline = datetime.now () - timedelta (days = limit)
logo = ''
if util.get_host().endswith('.br'):
cookie_django_language = 'pt-br'
logo = 'montao'
translation.activate(cookie_django_language)
self.request.COOKIES['django_language'] = cookie_django_language
dispatch= 'template/montaoli.html'
else:
cookie_django_language = self.request.get('cookie_django_language', '') if self.request.get('cookie_django_language', '') else self.request.get('hl', '')
dispatch= 'template/li.html'
if cookie_django_language:
if cookie_django_language == 'unset':
del self.request.COOKIES['django_language']
else:
self.request.COOKIES['django_language'] = cookie_django_language
self.reset_language()
next = None
bookmark = self.request.get("bookmark")
if not bookmark:
bookmark = = str(time.time())
category = self.request.get('cg')
q = self.request.get('q').encode("utf-8")
w = self.request.get('q')
cg = self.request.get('cg')
t = self.request.get('t')
f = self.request.get('f')
if cg and not t and not q and not f:#category without search
ads = Ad.all().filter("category =", cg).filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
elif q and not t and not cg and not f:#search without category
ads = Ad.all().search(self.request.get('q')).filter("published =", True)
ads = filter(lambda x: x.modified > timeline, ads)
ads = filter(lambda x: x.modified <= bookmark, ads)
ads = ads[:PAGESIZE+1]
ads = sorted(ads, key=lambda x: x.modified, reverse=True)
#iterate list keeping elements that are on timeline newer than bookmark
elif q and not t and cg and not f:
ads = Ad.all().search(q).filter("type =", 's').filter("category =", cg).filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
elif t and not f:
ads = Ad.all().filter("type =", 'w').filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
elif f == 'c':
ads = Ad.all().filter("company_ad =", True).filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
elif f == 'p':
ads = Ad.all().filter("company_ad =", False).filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
else:
if util.get_host().find('onta') > 1:
ads = Ad.all().filter("modified >", timeline).filter("published =", True).filter("url IN", ['www.montao.com.br','montao']).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
else:
ads = Ad.all().filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
if util.get_host().find('onta') > 1 and f == 'c':
ads = Ad.all().filter("company_ad =", True).filter("modified >", timeline).filter("published =", True).filter("url IN", ['www.montao.com.br','montao']).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
elif util.get_host().find('onta') > 1 and f == 'p':
ads = Ad.all().filter("company_ad =", False).filter("modified >", timeline).filter("published =", True).filter("url IN", ['www.montao.com.br','montao']).filter("modified <=", bookmark ).order("-modified").fetch(PAGESIZE+1)
if self.request.get('lat'):
m=int(self.request.get('r')) if self.request.get('r') else 804670
logging.info(m)
lat = self.request.get('lat')
lon = self.request.get('lon') if self.request.get('lon') else self.request.get('lng')
ads = Ad.proximity_fetch(Ad.all().filter("modified >", timeline).filter("published =", True).filter("modified <=", bookmark ).order("-modified") ,db.GeoPt(lat, lon),max_results=PAGESIZE+1, max_distance=m)
ads = sorted(ads, key=lambda x: x.modified, reverse=True)
if ads and len(ads) == PAGESIZE+1:
next = ads[-1].modified
ads = ads[:PAGESIZE]
template_values = 'twittername':twittername,'request':self.request,'lat':self.request.get('lat'),'lon':self.request.get('lon'),'q':q,'w':w,'cg':cg,'t':t,'logo':logo,'ads':ads, 'next':next, 'user':users.get_current_user(), 'bookmark':bookmark,'q':q, 'user_url': users.create_logout_url(self.request.uri) if users.get_current_user() else 'login',
'cg':category,'admin':users.is_current_user_admin(),
template_values.update(dict(current_user=self.current_user, facebook_app_id=FACEBOOK_APP_ID))
path = os.path.join(os.path.dirname(__file__), dispatch)
self.response.out.write(template.render(path, template_values))
更新 2:在这种情况下,我尝试使用 django 分页器类 from paginator import Paginator, InvalidPage, EmptyPage
,以下代码实际上分页数据集:
articles = Articles.all()
paginator = Paginator(articles,PAGESIZE)
articles = paginator.page(page)
所以我觉得这个解决方案很有吸引力,因为它非常简单易读,希望您能继续发表评论。
【问题讨论】:
【参考方案1】:在将书签传递给客户端之前,您可能需要对书签进行 base64 编码。 我已经尝试过[您的站点][1],但是如果没有服务器端错误消息,就无法清楚地回答您的问题。
此外,正如分页文章所提到的,直接使用日期时间作为书签会导致问题,而同一时间段内发布的文章不止一篇(在您的情况下,时间段为一分钟)。您可能需要考虑改用这种格式。
2008-10-26 04:38:00|aee15ab24b7b3718596e3acce04fba85
或者用秒来表示时间。
1310427763.47|aee15ab24b7b3718596e3acce04fba85
如果它是被查看的第一页,我应该将它设置为 datetime.now() 吗?
您只需忽略修改后的过滤器即可获得首页结果。 例如:
if bookmark:
suggestions = Suggestion.all().order("-when")
.filter('when <=', bookmark).fetch(PAGESIZE+1)
else:
suggestions = Suggestion.all().order("-when").fetch(PAGESIZE+1)
或使用当前时间作为书签。
import time
bookmark = str(time.time())
【讨论】:
谢谢你 lucemia。我应该尝试找到合适的格式。它现在显示的方式似乎不对。我将尝试使用秒来表示时间的方式,但我不确定如何使用书签变量,例如。如果它是被查看的第一页,我应该将它设置为 datetime.now() 吗? 您可以通过两种方式获取首页结果。两种方式都应该可以正常工作! 只要我能匹配时间格式就可以了。我可以通过使用来自 django 的日期时间对象来获得另一种工作方式,正如 Abdul 在这个问题 ***.com/questions/6014657/… 中所描述的那样【参考方案2】:Query cursors 正是为此而构建的。您应该使用它们而不是构建自己的解决方案。
【讨论】:
谢谢尼克,但后来在我的代码中,我使用了 IN 运算符,这似乎使查询游标不可用。 @Niklas 对于使用它的查询不可用,是的,但是您发布的查询不使用 IN。 好的,要么我可以重新处理不使用 IN 的查询,要么我使用 datetime 作为书签,直到我摆脱 IN 或更新游标以使用 IN以上是关于如何对数据集进行分页的主要内容,如果未能解决你的问题,请参考以下文章