我正在使用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)
但是我觉得我错过了一些东西,而且我无法从文档中找到它。
我应该在序列化程序中还是在视图中进行分页?
提前致谢。
答案 0 :(得分:3)
尝试PAGINATE_BY_PARAM
设置。这段代码应该让你非常接近:
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
我的代码片段使用通用视图来进行大量重复操作,我建议也让他们看看。 http://www.django-rest-framework.org/api-guide/generic-views
答案 1 :(得分:3)
让我们解决问题:
您需要创建一个允许用户定义页面大小的分页方法:
如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'
最后,您需要定义将在视图函数中使用的分页类。
以下示例仅适用于上述两种情况,只需将paginator
变量的值更改为PageNumberPaginator
或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)
现在你有了基于功能的视图和分页以及一个查询参数来改变页面大小。