Django Rest Framework按指定的GET参数分页

Lon*_*Dev 5 python django pagination django-rest-framework

我正在使用 Django REST 框架,我需要根据请求提供的 GET 参数对列表进行分页。

我知道我可以'PAGINATE_BY': 10在设置中进行设置,但是我想允许调用者在发出请求时指定他们想要分页的号码。

我目前有以下序列化程序:

from api.models import Countries
from rest_framework import serializers

class CountrySerializer(serializers.Serializer):
    country_geoname_id = serializers.CharField(required=True)
    country_code = serializers.CharField(source="iso", max_length=2L, required=True)
    country_name = serializers.CharField(max_length=64L, required=True)

    def transform_iso(self, obj, value):
        return "country_code"
Run Code Online (Sandbox Code Playgroud)

我尝试了以下观点:

@api_view(['GET'])
def country_list(request):
    """
    List all countries
    """
    if request.method == 'GET':
        queryset = Countries.objects.all()
        serializer = CountrySerializer(queryset, many=True, data=request.DATA)
        paginate_by = request.GET.get('limit', 10)
        return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)

但是我觉得我错过了一些东西,我一直无法从文档中弄清楚。

我应该在序列化程序中还是在视图中进行分页?

提前致谢。

Joh*_*fis 7

让我们把问题分解一下:

  1. 您需要创建一个允许用户定义页面大小的分页方法:

    PageNumberPaginationDRF 文档中所述,您可以通过覆盖以下内容来定义参数名称page_size_query_param

    如果设置,这是一个字符串值,指示查询参数的名称,该参数允许客户端基于每个请求设置页面大小。默认为None,表示客户端可能无法控制请求的页面大小。

    您可以通过以下方式之一实现:

    • settings.py添加以下内容:

      REST_FRAMEWORK = {
          'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
          'PAGE_SIZE': 10,
          'PAGINATE_BY_PARAM': 'page_size'
      }
      
      Run Code Online (Sandbox Code Playgroud)
    • 或者您可以创建一个自定义分页类并在那里覆盖您的设置:

      from rest_framework.pagination import PageNumberPagination
      
      class MyPagination(PageNumberPagination):
          page_size = 10
          page_size_query_param = 'page_size'
      
      Run Code Online (Sandbox Code Playgroud)
  2. 最后,您需要定义将在视图函数中使用的分页类。

    以下示例只需将paginator变量的值更改为PageNumberPaginatoror 即可适用于上述任何一种情况MyPaginator

    from rest_framework.pagination import PageNumberPagination
    
    @api_view(['GET'])
    def country_list(request):
    """
    List all countries
    """
    if request.method == 'GET':
        paginator = PageNumberPagination()
        queryset = Countries.objects.all()
        context = paginator.paginate_queryset(queryset, request)
        serializer = CountrySerializer(context, many=True)
        return paginator.get_paginated_response(serializer.data)
    
    Run Code Online (Sandbox Code Playgroud)

现在您拥有基于函数的视图,带有分页和查询参数来更改页面大小。