最近用django-el-pagination做列表展示,发现数据很多的时候加载很慢,在栈溢出上问了,也没人回...

说明

后来突然发现了原因,举直接返回的代码来说明,get_queryset函数返回列表数据,返回用了[::-1]倒序,而这样实际上导致了返回所有的数据再排序,在分页获取数据时,请求了所有的数据再切片,相当于mongodb中db.COLLECTION_NAME.find().sort({**:1}) 然后[::-1][(page-1)*NUMBER, page*NUMBER]

class IndexView(AjaxListView):
    template_name = '****'
    context_object_name = '****'
    page_template = '****'

    def get_queryset(self):
        return your_model.objects.filter(title='***').order_by('**')[::-1]

下面是改之后的代码,使用了order_by(-**)直接反向排序,其实在Django内部进行了处理,在分页数据库请求时就已经进行了倒序和切片,相当于mongodb中db.COLLECTION_NAME.find().sort({**:-1}).skip(NUMBER*page).limit(NUMBER)

    ...
    def get_queryset(self):
        return your_model.objects.filter(title='***').order_by('-**')

其他数据的操作

在项目中还用到了elasticsearch检索,对于其数据的分页,需要自己实现一个代理来进行分页操作。下面是搜索到的栈溢出上的代码。其中__len__函数返回数据的数量,__getitem__函数返回的是需要的数据,在请求的部分插入item.startitem.stop来指定数据,在elasticsearch-dsl中是在s.execute()执行请求前使用s[item.start:item.stop]指定数据。

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']