Google app engine 使用光标反向分页正在工作,但缺少一项
从中,我可以找到一个提示,如何通过颠倒顺序使用单个光标反向页面导航Google app engine 使用光标反向分页正在工作,但缺少一项,google-app-engine,app-engine-ndb,Google App Engine,App Engine Ndb,从中,我可以找到一个提示,如何通过颠倒顺序使用单个光标反向页面导航 class CursorTests(test_utils.NDBTest): def testFirst(self): class Bar(model.Model): value = model.IntegerProperty() self.entities = [] for i in range(10): e = Bar(value=i) e.put(
class CursorTests(test_utils.NDBTest):
def testFirst(self):
class Bar(model.Model):
value = model.IntegerProperty()
self.entities = []
for i in range(10):
e = Bar(value=i)
e.put()
self.entities.append(e)
q = Bar.query()
bars, next_cursor, more = q.order(Bar.key).fetch_page(3)
barz, another_cursor, more2 = q.order(-Bar.key).fetch_page(3, start_cursor=next_cursor)
self.assertEqual(len(bars), len(barz))
不幸的是,它失败了,出现了这个错误
回溯(最近一次调用上次):文件
“/Users/reiot/Documents/Works/appengine-ndb-experience/ndb/query\u-test.py”,
第32行,在testFirst中
self.assertEqual(len(bar),len(baz))断言者错误:3!=二,
是,反向查询中缺少边界中的项
bars = [Bar(key=Key('Bar', 1), value=0), Bar(key=Key('Bar', 2), value=1), Bar(key=Key('Bar', 3), value=2)]
bars = [Bar(key=Key('Bar', 2), value=1), Bar(key=Key('Bar', 1), value=0)]
如何解决这个问题?好的,这是正式的答案。您需要“反转”光标,如下所示:
rev_cursor = cursor.reversed()
我自己也不知道-(我将确保在fetch_page()的文档中显示这一点。处理这些多个游标,加上正向和反向查询不仅太复杂,而且不允许直接分页(转到第7页),页面底部有一组页面链接,如“>”,因为您不知道将有多少页面 出于这个原因,我的解决方案是获取整个结果集,或者至少是一个重要的结果集,例如对应于10个页面,然后进行简单的划分来处理页面,首先使用
keys_only=True
获取结果。确定与当前页面对应的集合后,执行key.get()在您的实体上。如果您愿意,可以考虑在MyC缓存中保存完整的密钥列表几分钟,这样查询就不会重新运行,尽管到目前为止我还没有发现这是必要的。
这是一个示例实现:
def session_list():
page = request.args.get('page', 0, type=int)
sessions_keys = Session.query().order(-Session.time_opened).fetch(100, keys_only=True)
sessions_keys, paging = generic_list_paging(sessions_keys, page)
sessions = ndb.get_multi(sessions_keys)
return render_template('generic_list.html', objects=sessions, paging=paging)
它使用了一个generic\u list\u paging
函数来进行分页划分,并在结果集中提取适当的子列表:
def generic_list_paging(objects, page, page_size=10):
nb_items = len(objects)
item_start = min(page * page_size, nb_items)
item_end = min((page + 1) * page_size, nb_items)
page_max = (nb_items - 1) // page_size + 1
objects = objects[item_start: item_end]
paging = {'page': page, 'page_max': page_max}
return objects, paging
最后,如果您使用的是Jinja2,下面是使用paging
dict的分页导航:
{% if paging.page_max > 1 %}
<nav>
<ul class="pagination">
{% if paging.page > 0 %}
<li>
<a href="{{ request.path }}?page={{ paging.page-1 }} aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for page in range(0,paging.page_max) %}
<li {% if page==paging.page %}class="disabled"{% endif %}><a href="{{ request.path }}?page={{ page }}">{{ page+1 }}</a></li>
{% endfor %}
{% if paging.page < paging.page_max-1 %}
<li>
<a href="{{ request.path }}?page={{ paging.page+1 }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{%if paging.page_max>1%}
{%如果paging.page>0%}
-
{%endif%}
{范围(0,paging.page_max)%%内的页的百分比}
{%endfor%}
{%if paging.page
{%endif%}
{%endif%}
问得好。我已经证实了这一点。我已经召集了专家。它在生产数据存储中是否也有这样的行为?这是我从一年开始在文档或新闻中搜索的内容:)文档早就被修复了。在上面的代码中,sessions=[sk.get()for sk In sessions\u keys]在性能方面并不好,它应该是一个get\u multi()。我刚修好。