2012-04-10 17 views
2

MongoDBカーソルオブジェクトをDjangoのdjango.core.paginator.Paginatorクラスと互換性があるように拡張する方法はありますか?MongoDBカーソルでDjangoのPaginatorクラスを使用する

また、Djangoのクラスを拡張することもできますか?

+0

私の一時的な解決策:https://gist.github.com/2351079 – Dor

答えて

0

あなたの一時的な解決策(https://gist.github.com/2351079)がよさそうだ - が、代わりにlist()ですべての結果をフェッチし、カーソルを強制し、[bottom:top]でページ付けの、多分明示カーソルに.skip().limit()を使用してみてくださいおそらくパフォーマンスが向上します。

+0

IIRCカーソル[foo:bar]はcursor.skip(foo)と同じです。 cursor.limit(bar-foo)、つまりリストを作成しません。 –

+0

そして、明確にするために、list(...)関数の使用は 'Page'クラスに限定されているので、カーソル全体ではなく、現在のページの結果だけを取得します。 – Dor

0

私は同じ問題に直面していて、動作する独自のPaginatorクラスを実装しました。ここでは、コードです:

from django.core.paginator import Paginator, Page 

class MongoPaginator(Paginator): 
    """ 
    Custom subclass of Django's Paginator to work with Mongo cursors. 
    """ 
    def _get_page(self, *args, **kwargs): 
     """ 
     Returns an instance of a single page. Replaced with our custom 
     MongoPage class. 
     """ 
     return MongoPage(*args, **kwargs) 

    def page(self, number): 
     """ 
     Returns a Page object for the given 1-based page number. 
     Important difference to standard Paginator: Creates a clone of the 
     cursor so we can get multiple slices. 
     """ 
     number = self.validate_number(number) 
     bottom = (number - 1) * self.per_page 
     top = bottom + self.per_page 
     if top + self.orphans >= self.count: 
      top = self.count 
     return self._get_page(
      self.object_list.clone()[bottom:top], number, self 
     ) 

class MongoPage(Page): 
    """ 
    Custom Page class for our MongoPaginator. Just makes sure the cursor is 
    directly converted to list so that we can use len(object_list). 
    """ 
    def __init__(self, object_list, number, paginator): 
     self.object_list = list(object_list) 
     self.number = number 
     self.paginator = paginator 

主な変更点は以下のとおりです。

  • スライスは、各ページには、直接にそれを変換する必要があり
  • カーソルごとに一度だけ動作するため、各ページには、カーソルのクローンを取得する必要がありますlen()が動作するリスト
関連する問題