を:
from django.core.paginator import Paginator, Page
class DSEPaginator(Paginator):
"""
Override Django's built-in Paginator class to take in a count/total number of items;
Elasticsearch provides the total as a part of the query results, so we can minimize hits.
"""
def __init__(self, *args, **kwargs):
super(DSEPaginator, self).__init__(*args, **kwargs)
self._count = self.object_list.hits.total
def page(self, number):
# this is overridden to prevent any slicing of the object_list - Elasticsearch has
# returned the sliced data already.
number = self.validate_number(number)
return Page(self.object_list, number, self)
、その後ビューで私が使用してPaginator
とElasticsearchクエリの間のプロキシです。 Paginator
には、__len__
(またはcount
)と__getitem__
(スライスが必要)という2つのものが必要です。プロキシのラフバージョンは、次のように機能します。
class ResultsProxy(object):
"""
A proxy object for returning Elasticsearch results that is able to be
passed to a Paginator.
"""
def __init__(self, es, index=None, body=None):
self.es = es
self.index = index
self.body = body
def __len__(self):
result = self.es.count(index=self.index,
body=self.body)
return result['count']
def __getitem__(self, item):
assert isinstance(item, slice)
results = self.es.search(
index=self.index,
body=self.body,
from_=item.start,
size=item.stop - item.start,
)
return results['hits']['hits']
プロキシインスタンスがPaginator
に渡すことができ、必要に応じてESへのリクエストを行います。
この例の 'count'プロパティは、合計ではなくページ内のアイテムの数を示しています。 paginatorの 'count' cached_propertyをオーバーライドして、合計カウントとして' _count'を返すことができます – Nasir