2012-04-10 54 views
2

是否有一種擴展MongoDB遊標對象的已知方法,使其與Django的django.core.paginator.Paginator類兼容?將Django的Paginator類與MongoDB遊標一起使用

或者,也許,擴展Django的類?

+0

我的臨時解決方案:https://gist.github.com/2351079 – Dor 2012-04-10 12:37:49

回答

0

您的臨時解決方案(https://gist.github.com/2351079)看起來不錯 - 但不是迫使遊標讀取與list()所有結果,並與[bottom:top]分頁,也許嘗試光標使用.skip().limit()明確 - 它可能會提高性能。

+0

IIRC遊標[foo:bar]與cursor.skip(foo)相同; cursor.limit(bar-foo),即它不創建列表。 – 2012-04-10 23:16:38

+0

只是爲了澄清:list(...)函數的使用僅限於'Page'類,所以它只提取當前頁面的結果,而不是整個遊標。 – Dor 2012-04-11 06:07:51

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()工作的列表