このページを正しく表示するにはJavascriptを有効にしてください。
AppEngine NDBでDjangoのペジネーターを使う
AppEngineだとRDBMSをサポートしていないので、
Djangoフレームワークの強力な機能の全部を利用することが出来ません。
今回はペジネーター(ページ分割を便利にしてくれる)機能を
NDB APIでも使いたかったので利用方法を調べてみました。
# 用語
## ペジネーター(Paginator)とは
データベースのデータを表示するとき、ページ分割して表示することよくありますよね。
そういうときDjangoのペジネーターという機能を利用するとものすごくはかどります。
オブジェクトのリストやQuerySetを渡すだけで、
「このページには◯番目から◯番目までのデータを表示する」とか
「次のページは存在するか」などをまとめて管理してくれます。
詳しい使い方は公式ドキュメント(↓)に任せますが、とにかく便利な機能です。
[ペジネータ (paginator)](http://docs.djangoproject.jp/en/latest/topics/pagination.html)
## NDBとは
[What's NDB?](https://docs.google.com/presentation/d/1FDbkr0AoGxPOcEdaEjRb3ENxltxNxKTsdJW2PnmPU-8/edit#slide=id.p)
このスライドが使い方等含めて詳しいです。
従来のDB APIを置き換える高機能なAPIなのですが、
リリースされて結構経つのに日本語の資料があまりない現状です。
-------
# NDBでペジネーターを使う
では本題に移ります。
## DB API用 GAE_Paginator
探してみたところ、旧DB API向けのペジネーター利用方法がありました。
[Extend django.core.paginator Paginator to work with Google App Engine](http://stackoverflow.com/questions/2679370/extend-django-core-paginator-paginator-to-work-with-google-app-engine)
どうもPaginatorを継承して、page関数を上書きしてあげれば
AppEngineでもペジネーターを利用することが可能みたいです。
## NDB向けに書き換える
上に載っているままだとNDBでは利用できないので、
これをベースに書き換えてみました。
:::python
# -*- coding: utf-8 -*-
from django.core.paginator import Paginator, Page
class GAENdbPaginator(Paginator):
def page(self, number):
number = self.validate_number(number)
offset = (number - 1) * self.per_page
if offset+self.per_page + self.orphans >= self.count:
top = self.count
return Page(self.object_list.fetch(self.per_page, offset = offset), number, self)
あまり大した書き換えはしてませんが、こんな感じになります。
### NDBで使ってみる
:::python
class Item(ndb.Model):
item_id = ndb.IntegerProperty()
item_name = ndb.StringProperty()
created_at = ndb.DateTimeProperty(auto_now_add = True)
@classmethod
def getQuery(cls):
query = cls.query().order(-cls.created_at)
return query
# 1ページ 10件
COUNT = 10
# queryオブジェクト取得
query = Item.getQuery()
# queryオブジェクトをページング
p = GAENdbPaginator(query, COUNT)
# 1ページめ(1から始まる)の情報を取得
this_page = p.page(1)
## 以下からは普通テンプレートに渡して使う
this_page.object_list
this_page.has_next()
this_page.next_page_number()
こんな感じでNDBでもペジネーターが利用できるようになりました。