如何在 django-rest-framework 中使用 pagination_class 进行自定义分页 class
How can I use pagination_class in django-rest-framework for my custom pagination class
我的分页Class
class ArticleListPagination(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
我的文章视图Class
class Article(generics.GenericAPIView):
queryset = Articles.objects.all()
serializer_class = ArticlesSerializer
pagination_class = ArticleListPagination
def get(self, request):
queryset = self.get_queryset()
serializer = ArticlesSerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
我可以使用自定义分页 class 使用这个
def get(self, request):
queryset = self.get_queryset()
page = ArticleListPagination()
new = page.paginate_queryset(queryset, request)
serializer = ArticlesSerializer(new, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
ArticleListPagination
的使用方法正确吗?如果我在 class 中声明我的分页 class 是 ArticleListPagination
,为什么它不更改 return 查询集对象。
for django_rest_framework 3.0.x(或以下):
您可以直接扩展 rest_framework.mixins.ListModelMixin
,或者实现与此类似的 get
或 list
方法。
当然generics.GenericAPIView
也是需要的
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
# get_paginaion_serializer will read your DEFAULT_PAGINATION_SERIALIZER_CLASS
# or view.pagination_serializer_class
# we will talk the two variable later
serializer = self.get_pagination_serializer(page)
else:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
如果你想配置它“全局”,你可以在你的settings.py
中配置
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_SERIALIZER_CLASS': 'YourCustomPaginationSerializer',
# ...
}
如果您只想设置特定视图:
属性是 pagination_serializer_class
而不是 pagination_class
。
class MyView(generics.GenericAPIView):
pagination_serializer_class = YourCustomPaginationSerializerClass
for django_rest_framework 3.1.x:
略有不同,您可以先查看文档。 3.1 Announcement , Pagination Docs
您可以直接扩展 rest_framework.mixins.ListModelMixin
,或者实现与此类似的 get
方法。
当然generics.GenericAPIView
也是需要的
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
如果你想配置它“全局”,你可以在你的settings.py
中配置
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
# ...
}
如果您只想设置特定视图:
class MyView(generics.GenericAPIView):
pagination_class = YourCustomPaginationClass
您可以在视图集中使用自定义分页并在自定义视图中进行更改
pagination.py
class OneByOneItems(pagination.PageNumberPagination):
page_size = 2
def get_paginated_response(self, data):
return Response(OrderedDict([
('lastPage', self.page.paginator.count),
('countItemsOnPage', self.page_size),
('current', self.page.number),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
views.py
class LectionViewSet(viewsets.ReadOnlyModelViewSet):
queryset = LectionCourse.objects.all().order_by('-created_at')
serializer_class = LectionSerializer
@list_route(methods=['get'], url_path='get-lections/(?P<pk>[^/]+)')
def get_lection(self, request, pk):
self.pagination_class = OneByOneItems
queryset = self.filter_queryset(self.queryset.filter(course=pk))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
serializers.py
class CourseSerializer(serializers.ModelSerializer):
author = UserCreatorSerializer(many=True)
project = ProjectSerializer(many=True)
class Meta:
model = Course
fields = ('id', 'theme', 'author', 'project')
class LectionSerializer(serializers.HyperlinkedModelSerializer):
choose_course = CourseSerializer(source='course')
class Meta:
model = LectionCourse
fields = ('id', 'title', 'video', 'preview_description', 'number', 'choose_course')
我更喜欢使用自定义分页,因为它允许您根据您的要求修改您的回复。这种方法不需要太多努力。
下面是我的代码...希望这会有所帮助。
custom_pagination.py
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response
class CustomPagination(LimitOffsetPagination):
def get_paginated_response(self, data):
return Response({
"status": True,
"code": status.HTTP_200_OK,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'count': self.count,
'results': data
})
在您看来,您需要做的就是调用两个函数,即 paginate_queryset 和您在分页中创建的函数 class get_paginated_response。 "pagination_queryset" 将查询集作为参数并将结果传递给您的序列化程序,最后调用 "get_paginated_response" 将序列化数据作为参数并在结果中 return 响应。
page = self.paginate_queryset(query_set)
serializer_class = <Your Serializer>(page, many=True,)
return self.get_paginated_response(serializer_search_user.data)
最后在 "settings.py" 中声明您的自定义序列化 class。
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':'<your_app>.<your_peckage>.custom_pagination.CustomPagination',
'PAGE_SIZE': 5
}
我的分页Class
class ArticleListPagination(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
我的文章视图Class
class Article(generics.GenericAPIView):
queryset = Articles.objects.all()
serializer_class = ArticlesSerializer
pagination_class = ArticleListPagination
def get(self, request):
queryset = self.get_queryset()
serializer = ArticlesSerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
我可以使用自定义分页 class 使用这个
def get(self, request):
queryset = self.get_queryset()
page = ArticleListPagination()
new = page.paginate_queryset(queryset, request)
serializer = ArticlesSerializer(new, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
ArticleListPagination
的使用方法正确吗?如果我在 class 中声明我的分页 class 是 ArticleListPagination
,为什么它不更改 return 查询集对象。
for django_rest_framework 3.0.x(或以下):
您可以直接扩展 rest_framework.mixins.ListModelMixin
,或者实现与此类似的 get
或 list
方法。
当然generics.GenericAPIView
也是需要的
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
# get_paginaion_serializer will read your DEFAULT_PAGINATION_SERIALIZER_CLASS
# or view.pagination_serializer_class
# we will talk the two variable later
serializer = self.get_pagination_serializer(page)
else:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
如果你想配置它“全局”,你可以在你的settings.py
中配置REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_SERIALIZER_CLASS': 'YourCustomPaginationSerializer',
# ...
}
如果您只想设置特定视图:
属性是 pagination_serializer_class
而不是 pagination_class
。
class MyView(generics.GenericAPIView):
pagination_serializer_class = YourCustomPaginationSerializerClass
for django_rest_framework 3.1.x:
略有不同,您可以先查看文档。 3.1 Announcement , Pagination Docs
您可以直接扩展 rest_framework.mixins.ListModelMixin
,或者实现与此类似的 get
方法。
当然generics.GenericAPIView
也是需要的
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
如果你想配置它“全局”,你可以在你的settings.py
中配置REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
# ...
}
如果您只想设置特定视图:
class MyView(generics.GenericAPIView):
pagination_class = YourCustomPaginationClass
您可以在视图集中使用自定义分页并在自定义视图中进行更改
pagination.py
class OneByOneItems(pagination.PageNumberPagination):
page_size = 2
def get_paginated_response(self, data):
return Response(OrderedDict([
('lastPage', self.page.paginator.count),
('countItemsOnPage', self.page_size),
('current', self.page.number),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
views.py
class LectionViewSet(viewsets.ReadOnlyModelViewSet):
queryset = LectionCourse.objects.all().order_by('-created_at')
serializer_class = LectionSerializer
@list_route(methods=['get'], url_path='get-lections/(?P<pk>[^/]+)')
def get_lection(self, request, pk):
self.pagination_class = OneByOneItems
queryset = self.filter_queryset(self.queryset.filter(course=pk))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
serializers.py
class CourseSerializer(serializers.ModelSerializer):
author = UserCreatorSerializer(many=True)
project = ProjectSerializer(many=True)
class Meta:
model = Course
fields = ('id', 'theme', 'author', 'project')
class LectionSerializer(serializers.HyperlinkedModelSerializer):
choose_course = CourseSerializer(source='course')
class Meta:
model = LectionCourse
fields = ('id', 'title', 'video', 'preview_description', 'number', 'choose_course')
我更喜欢使用自定义分页,因为它允许您根据您的要求修改您的回复。这种方法不需要太多努力。
下面是我的代码...希望这会有所帮助。
custom_pagination.py
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response
class CustomPagination(LimitOffsetPagination):
def get_paginated_response(self, data):
return Response({
"status": True,
"code": status.HTTP_200_OK,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'count': self.count,
'results': data
})
在您看来,您需要做的就是调用两个函数,即 paginate_queryset 和您在分页中创建的函数 class get_paginated_response。 "pagination_queryset" 将查询集作为参数并将结果传递给您的序列化程序,最后调用 "get_paginated_response" 将序列化数据作为参数并在结果中 return 响应。
page = self.paginate_queryset(query_set)
serializer_class = <Your Serializer>(page, many=True,)
return self.get_paginated_response(serializer_search_user.data)
最后在 "settings.py" 中声明您的自定义序列化 class。
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':'<your_app>.<your_peckage>.custom_pagination.CustomPagination',
'PAGE_SIZE': 5
}