GAE/Pでページネーションを実装する方法

~バクバクなってるー鼓動旅の始まりの合図さ~
今日はGAE/Pでページネーションを実装する方法について書いてみます。

リクエストURLはhttp://localhost:8080/gae_test/index?page=hogehogeを想定しています。
hogehogeのところに数値が入る仕組みですね。
そのURLにリクエストしたとき、ざっと以下のコードで
1ページに5個だけデータを表示します。

import math
_MAXDISPLAYSIZE=5

def get(self):
  next = None
  data = Data.all()
  count = data.count()
  maxpage = int(math.ceil(float(count)/_MAXDISPLAYSIZE))
  page = self.request.get('page')
  if page:
    page = long(page)
  else:
    # toppage
    page = 1
  data = data.order("-__key__").fetch(_MAXDISPLAYSIZE+1, (page-1)*_MAXDISPLAYSIZE)
  # adjust display size
  if len(data) == _MAXDISPLAYSIZE+1:
    next = page + 1
    data = data[:_MAXDISPLAYSIZE]
  prev = page - 1
  if prev < 0:
    prev = 0

  #
  # template render
  #
 
Google CodeのGqlQueryクラスの説明が参考になります。
http://code.google.com/intl/ja/appengine/docs/python/datastore/gqlqueryclass.html

今回のポイント1つ目はfetchメソッドです。
fetch(limit,offset=0)は、limitでクエリの結果を返す数を制限し、offsetで結果をスキップする数を指定します。

例えば2ページ目を表示しようとしていたとき、以下のコードによりdataをkeyで降順に並び替えた後、 5レコードスキップし、その後から6レコードを結果として返します。
data = data.order("-__key__").fetch(_MAXDISPLAYSIZE+1, (page-1)*_MAXDISPLAYSIZE)

次のポイントはわざとfetchするサイズを_MAXDISPLAYSIZE+1にしていることですね。
限界値+1を取って、取れたら次のページが存在すると判定しています。
あとはテンプレート側で、若干省略しましたが、以下のように書けばページネーションの完成です。
{% if prev %}前へ ...{% endif %}
{{ page }}
{% if next %}... {{ maxpage }} 次へ{% endif %}

ずっと夜明けのBEATを聞いて書いてたので今日は夜明けのBEAT。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
何かぼんやりと勉強会をしたいなぁと思っています。
ネタ募集中です。
関西で開催する予定ですので、関西の方はお楽しみに!

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

コメント

このブログの人気の投稿

perlのMIME::Liteならメール送信はすぐ書ける。その2

GAEでOAuthというかTwitter認証してみた。

Pray For Japanのまとめページつくりました。