【问题标题】:How to paginate response from function based view of django rest framework?如何从 django rest 框架的基于函数的视图中对响应进行分页?
【发布时间】:2016-03-06 17:33:56
【问题描述】:

我已经编写了如下代码 sn-p,我需要在其中实现分页,请告诉我这怎么可能。另外由于某些原因,我只想使用基于函数的视图。

@api_view(['GET'])
@permission_classes([AllowAny])
def PersonView(request):
    context={'request': request}
    person_objects = Person.objects.all()
    if len(person_objects) > 0:
        person_data = PersonSerializer(person_objects, many=True, context=context)
        return Response(person_data.data, status=status.HTTP_200_OK)
    else:
        return Response({}, status=status.HTTP_200_OK)

【问题讨论】:

  • 有什么问题?
  • 为什么需要是函数视图?你不能把它改成ListView吗?..

标签: django pagination django-rest-framework


【解决方案1】:

http://www.django-rest-framework.org/api-guide/pagination/

from rest_framework.pagination import PageNumberPagination

@api_view(['GET',])

@permission_classes([AllowAny,])

def PersonView(request):

    paginator = PageNumberPagination()
    paginator.page_size = 10
    person_objects = Person.objects.all()
    result_page = paginator.paginate_queryset(person_objects, request)
    serializer = PersonSerializer(result_page, many=True)
    return paginator.get_paginated_response(serializer.data)

【讨论】:

  • 它对我有用,但是没有使用上下文,所以我认为你应该忽略它。
  • 如果你想从请求 GET 参数中获取指定页面怎么办?
【解决方案2】:

您还可以通过覆盖 PageNumberPagination 来定义自定义分页类

分页.py

from rest_framework import pagination
class StandardResultsSetPagination(pagination.PageNumberPagination):
    page_size = 10
    page_query_param = 'page'
    page_size_query_param = 'per_page'
    max_page_size = 1000

这将有助于定义

page_size、页面查询自定义参数和max_page_size

views.py

from rest_api.pagination import StandardResultsSetPagination

@api_view(['GET',])
@permission_classes([AllowAny,])
def PersonView(request):
    person_objects = Person.objects.all()
    if len(person_objects)> 0:
        paginator = StandardResultsSetPagination()
        result_page = paginator.paginate_queryset(person_objects, request)
        serializer = PersonSerializer(result_page, many=True)
        return paginator.get_paginated_response(serializer.data)
    else:
        return Response({},status=status.HTTP_200_OK)

例如: 请求

GET https://api.example.org/persons/?page=1&per_page=10

回应

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/persons/?page=2&per_page=10",
    "previous": null,
    "results": [
       …
    ]
}

【讨论】:

    【解决方案3】:

    接受的答案有一个错误

    ModelSerializer 接受查询集或对象,在接受的答案中,PersonSerializer 的输出为 paginator.paginate_queryset,它返回包含 Page 类的单个元素的 list,因此序列化程序将返回不完整的数据或根本没有数据(知道这一点,因为已经尝试并看到了错误的结果)。

    这可以通过将实际查询集传递给序列化程序来轻松解决,在本例中为person_objects

    所以最终的代码是,

    from rest_framework.pagination import PageNumberPagination
    
    @api_view(['GET',])
    @permission_classes([AllowAny,])
    def PersonView(request):
        paginator = PageNumberPagination()
        paginator.page_size = 10
        person_objects = Person.objects.all()
        result_page = paginator.paginate_queryset(person_objects, request)
        serializer = PersonSerializer(person_objects, many=True)  # MAIN CHANGE IS HERE
        return paginator.get_paginated_response(serializer.data)
    

    这修复了错误,但将完整的查询集传递给序列化程序将花费大量时间进行序列化,因为序列化程序采用惰性方法,但这个性能问题本身就是一个新问题。

    【讨论】:

      猜你喜欢
      • 2020-04-12
      • 2022-01-24
      • 2018-11-19
      • 2016-01-23
      • 2020-12-04
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      相关资源
      最近更新 更多