插件窝 干货文章 Django REST Framework关联查询如何实现分页?

Django REST Framework关联查询如何实现分页?

Author Framework PAGINATION import 196    来源:    2025-03-15

在Django REST Framework (DRF) 中,关联查询的分页可以通过使用DRF提供的分页器来实现。DRF提供了几种内置的分页器,如 PageNumberPaginationLimitOffsetPaginationCursorPagination。你可以根据需求选择合适的分页器。

假设你有一个模型 Author 和一个模型 Book,并且 Book 通过外键关联到 Author。你想要在查询某个作者的所有书籍时进行分页。

1. 使用 PageNumberPagination

PageNumberPagination 是最常用的分页方式,它基于页码进行分页。

步骤:

  1. 定义分页器:你可以在 settings.py 中全局配置分页器,或者在视图中局部配置。

    # settings.py
    REST_FRAMEWORK = {
       'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
       'PAGE_SIZE': 10,  # 每页显示的记录数
    }
    
  2. 在视图中使用分页器:如果你不想全局配置,可以在视图中局部配置。

    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)
    
  3. 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'),
    ]
    

2. 使用 LimitOffsetPagination

LimitOffsetPagination 允许客户端指定从哪条记录开始(offset)以及返回多少条记录(limit)。

步骤:

  1. 定义分页器

    # settings.py
    REST_FRAMEWORK = {
       'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
       'PAGE_SIZE': 10,
    }
    
  2. 在视图中使用分页器

    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)
    

3. 使用 CursorPagination

CursorPagination 基于游标的分页,适用于大数据集的分页,因为它不会受到新数据插入的影响。

步骤:

  1. 定义分页器

    # settings.py
    REST_FRAMEWORK = {
       'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
       'PAGE_SIZE': 10,
    }
    
  2. 在视图中使用分页器

    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:适用于大数据集的分页,基于游标。

你可以根据具体的业务需求选择合适的分页方式,并在视图中进行配置。