在Django REST Framework (DRF) 中,PageNumberPagination
并不会查询全库数据。它只会查询当前页所需的数据,从而避免不必要的数据库查询和内存消耗。
分页查询:当你使用 PageNumberPagination
时,DRF 会根据请求中的 page
参数和 page_size
参数(或默认值)来生成一个分页查询。这个查询只会获取当前页的数据,而不是整个数据库中的所有数据。
数据库优化:DRF 的分页机制利用了数据库的 LIMIT
和 OFFSET
功能。例如,如果你请求第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 还提供了其他分页类,如 LimitOffsetPagination
和 CursorPagination
,它们也有各自的优势和适用场景。