【问题标题】:Django Rest Framework Paginate By Specified GET ParameterDjango Rest框架按指定的GET参数分页
【发布时间】:2013-11-24 13:19:16
【问题描述】:

我正在使用 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"

我尝试了以下观点:

@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)

但是我觉得我遗漏了一些东西,并且我无法从文档中弄清楚。

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

提前致谢。

【问题讨论】:

标签: python django pagination django-rest-framework


【解决方案1】:

让我们分解问题:

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

    如 DRF 文档中的 PageNumberPagination 所述,您可以通过覆盖 page_size_query_param 来定义参数名称:

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

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

    • settings.py 中添加以下内容:

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

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

    只需将paginator 变量的值更改为PageNumberPaginatorMyPaginator,以下示例将适用于上述任何一种情况:

    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)
    

现在您有了基于功能的视图,其中包含分页和用于更改页面大小的查询参数。

【讨论】:

  • 太棒了!有没有办法从MyPagination 类本身检索page_size 值,如果超过限制则返回错误?我问这个是因为我不想在每个 viewviewSet 上验证它
  • @Juan-Kabbali 谢谢!是的,如果您正在创建 MyPagination 类的实例,您可以通过点符号检索属性的值:my_pagination_instance.page_size
【解决方案2】:

尝试PAGINATE_BY_PARAM 设置。这个 sn-p 应该让你非常接近:

class CountryListView(ListAPIView):
    model = Countries
    serializer_class = CountrySerializer
    paginate_by_param = 'limit'

http://www.django-rest-framework.org/api-guide/pagination#pagination-in-the-generic-views

我的 sn-p 使用通用视图来消除很多重复,我建议也看看这些。 http://www.django-rest-framework.org/api-guide/generic-views

【讨论】:

    猜你喜欢
    • 2021-05-06
    • 2016-06-20
    • 1970-01-01
    • 2018-09-16
    • 2015-06-05
    • 1970-01-01
    • 2017-11-27
    • 2014-08-25
    • 1970-01-01
    相关资源
    最近更新 更多