在Django REST Framework (DRF) 中,关联查询的分页可以通过使用DRF提供的分页器来实现。DRF提供了几种内置的分页器,如 PageNumberPagination
、LimitOffsetPagination
和 CursorPagination
。你可以根据需求选择合适的分页器。
假设你有一个模型 Author
和一个模型 Book
,并且 Book
通过外键关联到 Author
。你想要在查询某个作者的所有书籍时进行分页。
PageNumberPagination
PageNumberPagination
是最常用的分页方式,它基于页码进行分页。
定义分页器:你可以在 settings.py
中全局配置分页器,或者在视图中局部配置。
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10, # 每页显示的记录数
}
在视图中使用分页器:如果你不想全局配置,可以在视图中局部配置。
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from .models import Author, Book
from .serializers import BookSerializer
class BookPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
class AuthorBooksListView(generics.ListAPIView):
serializer_class = BookSerializer
pagination_class = BookPagination
def get_queryset(self):
author_id = self.kwargs['author_id']
return Book.objects.filter(author_id=author_id)
URL 配置:在 urls.py
中配置路由。
from django.urls import path
from .views import AuthorBooksListView
urlpatterns = [
path('authors/<int:author_id>/books/', AuthorBooksListView.as_view(), name='author-books'),
]
LimitOffsetPagination
LimitOffsetPagination
允许客户端指定从哪条记录开始(offset
)以及返回多少条记录(limit
)。
定义分页器:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 10,
}
在视图中使用分页器:
from rest_framework import generics
from rest_framework.pagination import LimitOffsetPagination
from .models import Author, Book
from .serializers import BookSerializer
class BookPagination(LimitOffsetPagination):
default_limit = 10
max_limit = 100
class AuthorBooksListView(generics.ListAPIView):
serializer_class = BookSerializer
pagination_class = BookPagination
def get_queryset(self):
author_id = self.kwargs['author_id']
return Book.objects.filter(author_id=author_id)
CursorPagination
CursorPagination
基于游标的分页,适用于大数据集的分页,因为它不会受到新数据插入的影响。
定义分页器:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 10,
}
在视图中使用分页器:
from rest_framework import generics
from rest_framework.pagination import CursorPagination
from .models import Author, Book
from .serializers import BookSerializer
class BookPagination(CursorPagination):
page_size = 10
ordering = '-created_at' # 按创建时间倒序排列
class AuthorBooksListView(generics.ListAPIView):
serializer_class = BookSerializer
pagination_class = BookPagination
def get_queryset(self):
author_id = self.kwargs['author_id']
return Book.objects.filter(author_id=author_id)
PageNumberPagination
:适用于简单的分页需求,基于页码。LimitOffsetPagination
:适用于需要灵活控制分页的场景,基于偏移量和限制数。CursorPagination
:适用于大数据集的分页,基于游标。你可以根据具体的业务需求选择合适的分页方式,并在视图中进行配置。