DjangoのPaginatorが変わってるよ。

Djangor7306ObjectPaginator がdeprecated扱いになったので、 どんな風に変わったのか調べてみたよ。

テストを走らせてみると、こんな感じのWarningを思いっきり吐かれた。

DeprecationWarning: The ObjectPaginator is deprecated. Use django.core.paginator.Paginator instead.

なるほど、 Paginator に変わったらしい。 実際にどう変わったのかな?って確認しようと、 django/core/paginator.py をちょっと覗いてみると、 QuerySetPaginator って派生クラスもある。 どこが違うかと言うと、 _get_count なメソッドだけがオーバーライドされてる。

まずは Paginator_get_count を見てみるとこうなってる。

def _get_count(self):
    "Returns the total number of objects, across all pages."
    if self._count is None:
        self._count = len(self.object_list) # <-- lenでカウントを取得
    return self._count
count = property(_get_count)

_countなプロパティがセットされて無ければ、 lenを使ってカウントを取得してる。

今度は QuerySetPaginator_get_count を見てみる。

def _get_count(self):
    if self._count is None:
        self._count = self.object_list.count() # <-- QuerySetのcountをコール
    return self._count
count = property(_get_count)

_countなプロパティがセットされて無ければ、 QuerySet のcountをコールして、COUNTなSQLを発行してカウントを取得してる。なるほどー。 って事は、 Paginator を使うよりも、 QuerySetPaginator を使う方が良いね。 今までの ObjectPaginatorQuerySet しか扱えなかったんだから、 WarningでもQuerySetPaginator insteadって出して欲しいなぁ。ってか出すべきな気がする。

念のために汎用ビューを見てみると、 やっぱり QuerySetPaginator を使ってるよ。

もう一つ、今回の変更で加わったのが Page なクラス。 今まで ObjectPaginatorget_page をコールすると、 返り値は QuerySet だった。

try:
    # 返り値のobject_listはQuerySet
    object_list = paginator.get_page(page - 1)
except InvalidPage:
    raise Http404

それが Paginatorpage をコールした時の返り値は Page になる。

try:
    # 返り値のpage_objはPage
    # マイナス1しなくて良くなった!
    page_obj = paginator.page(page)
except InvalidPage:
    raise Http404

# Pageの持つobject_listプロパティにQuerySetが入ってる
object_list = page_obj.object_list

この Page なクラスはページネイション関連のデータを保持する実装になっていて、 汎用ビューで今まで使えてたページネイション関連の変数は、 全部この Page がメソッドとして実装してる。 結構な変更がかかってるけども、 明らかに使いやすくなってると思う。 今までのがデータの引き回しとかが多くて、微妙に使いづらかったってのもあるけども :-P

ObjectPaginatorQuerySetPaginator にリプレイスする時は、 django/views/generic/list_detail.py を見れば分かりやすいと思うよ :-)

Posted at: 
2008/03/26 03:31:44
2 Comments
1 TrackBack
Tags: 
Django
Python
Trackback: 
http://humming.via-kitchen.com/2008/03/26/change-paginator-on-django/trackback/

TrackBacks

[Django]巡回 - 常山日記

Django Snippets: Forms splitted in fieldsets FormMail Clone Django and Twill Versioned media files using template tags Blog: [Python][Django]汎用ビューでextra_contextを使うときの遅延評価 Djangoインストール(Windows) Djangoで遊ぶ その1 DjangoのPaginato

Created at: 
2008/03/26 12:32:50

Comments

ENDLESS

とても親切な説明で助かりまっす!
自分もチョクチョクリビジョン上げないと!

Created at: 
2008/03/26 08:13:47

nobu

>某endless氏
我が家もまだ未対応 :-P
今週末にガッツリ対応する予定っす。

Created at: 
2008/03/26 11:50:48

Add Comment

Add Comment