Smi*_*lls 9 python django postgresql pagination django-rest-framework
我在Django Rest框架中进行了分页,看起来速度非常慢.Count看起来像罪魁祸首,由于表中数百万行,每次返回都要花费数百毫秒.
我使用postgresql作为数据库.有没有办法不计算行数仍然使用分页?如果我手动过滤了查询集,则在启用此功能之前性能很好.
Flo*_*ian 14
问题是,用于计数的查询与用于获取数据的潜在复杂查询相同。这样比较浪费。PageNumberPagination在Paginator内部使用 Django 自己的。
为了使计数查询更简单,覆盖分页器类 DRF 使用:
from django.core.paginator import Paginator
from django.utils.functional import cached_property
from rest_framework.pagination import PageNumberPagination
class FasterDjangoPaginator(Paginator):
@cached_property
def count(self):
# only select 'id' for counting, much cheaper
return self.object_list.values('id').count()
class FasterPageNumberPagination(PageNumberPagination):
django_paginator_class = FasterDjangoPaginator
Run Code Online (Sandbox Code Playgroud)
覆盖get_paginated_response分页类的方法,不包括计数.您可以参考基本实现了的PageNumberPagination类来看看你应该返回什么.
from rest_framework.pagination import PageNumberPagination
from collections import OrderedDict # requires Python 2.7 or later
class PageNumberPaginationWithoutCount(PageNumberPagination):
# Set any other options you want here like page_size
def get_paginated_response(self, data):
return Response(OrderedDict([
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
Run Code Online (Sandbox Code Playgroud)
然后在你的settings.py,设置DEFAULT_PAGINATION_CLASS你的新分页课程.
DEFAULT_PAGINATION_CLASS = 'path.to.PageNumberPaginationWithoutCount'
Run Code Online (Sandbox Code Playgroud)
编辑:从下面的评论中听起来这可能不足以阻止慢速sql查询,所以你可能还需要覆盖paginate_queryset.
如果你不需要计数,下一个和上一个链接就可以了,可以使用以下自定义类。
import sys
from collections import OrderedDict
from django.core.paginator import Paginator
from django.utils.functional import cached_property
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class CustomPaginatorClass(Paginator):
@cached_property
def count(self):
return sys.maxsize
# To Avoid large table count query, We can use this paginator class
class LargeTablePagination(PageNumberPagination):
django_paginator_class = CustomPaginatorClass
def get_paginated_response(self, data):
return Response(OrderedDict([
('page', self.page.number),
('results', data)
]))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3524 次 |
| 最近记录: |