插件窝 干货文章 Django分页:DRF的PageNumberPagination会查询全库数据吗?

Django分页:DRF的PageNumberPagination会查询全库数据吗?

self paginator 查询 PageNumberPagina 807    来源:    2025-03-15

在Django REST Framework (DRF) 中,PageNumberPagination 并不会查询全库数据。它只会查询当前页所需的数据,从而避免不必要的数据库查询和内存消耗。

工作原理

  1. 分页查询:当你使用 PageNumberPagination 时,DRF 会根据请求中的 page 参数和 page_size 参数(或默认值)来生成一个分页查询。这个查询只会获取当前页的数据,而不是整个数据库中的所有数据。

  2. 数据库优化:DRF 的分页机制利用了数据库的 LIMITOFFSET 功能。例如,如果你请求第2页,每页10条数据,DRF 会生成类似 LIMIT 10 OFFSET 10 的 SQL 查询,这样数据库只会返回第11到20条记录,而不是所有记录。

示例

假设你有一个包含1000条记录的 Book 模型,并且你使用 PageNumberPagination 进行分页。

from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Book
from .serializers import BookSerializer

class BookListView(APIView):
    pagination_class = PageNumberPagination

    def get(self, request):
        books = Book.objects.all()
        page = self.paginate_queryset(books)
        if page is not None:
            serializer = BookSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)

    @property
    def paginator(self):
        if not hasattr(self, '_paginator'):
            if self.pagination_class is None:
                self._paginator = None
            else:
                self._paginator = self.pagination_class()
        return self._paginator

    def paginate_queryset(self, queryset):
        if self.paginator is None:
            return None
        return self.paginator.paginate_queryset(queryset, self.request, view=self)

    def get_paginated_response(self, data):
        assert self.paginator is not None
        return self.paginator.get_paginated_response(data)

在这个例子中,当你请求 /books/?page=2&page_size=10 时,DRF 会生成一个查询,只获取第11到20条记录,而不是所有1000条记录。

总结

PageNumberPagination 不会查询全库数据,它只会查询当前页所需的数据。这种分页机制是高效的,因为它利用了数据库的分页功能,避免了不必要的数据加载和内存消耗。

如果你有更多的数据分页需求,DRF 还提供了其他分页类,如 LimitOffsetPaginationCursorPagination,它们也有各自的优势和适用场景。