您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Django Rest Framework 3.1打破了分页.PaginationSerializer

Django Rest Framework 3.1打破了分页.PaginationSerializer

我不确定这是否是完全正确的方法,但是它可以满足我的需求。它使用Django Paginator和自定义序列化程序。

这是我的View类,它检索对象以进行序列化

class CourseListView(AuthView):
    def get(self, request, format=None):
        """
        Returns a JSON response with a listing of course objects
        """
        courses = Course.objects.order_by('name').all()
        serializer = PaginatedCourseSerializer(courses, request, 25)
        return Response(serializer.data)

这是使用我的Course序列化程序的被黑客入侵的序列化程序。

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

class PaginatedCourseSerializer():
    def __init__(self, courses, request, num):
        paginator = Paginator(courses, num)
        page = request.QUERY_PARAMS.get('page')
        try:
            courses = paginator.page(page)
        except PageNotAnInteger:
            courses = paginator.page(1)
        except EmptyPage:
            courses = paginator.page(paginator.num_pages)
        count = paginator.count

        prevIoUs = None if not courses.has_prevIoUs() else courses.prevIoUs_page_number()
        next = None if not courses.has_next() else courses.next_page_number()
        serializer = CourseSerializer(courses, many=True)
        self.data = {'count':count,'prevIoUs':prevIoUs,
                 'next':next,'courses':serializer.data}

这给了我一个类似于旧分页器所给出的行为的结果。

{
    "prevIoUs": 1,
    "next": 3,
    "courses": [...],
    "count": 384
}

我希望这有帮助。我仍然认为必须使用新的API来实现此目的,但这还没有被很好地记录。如果我发现更多问题,我将编辑我的帖子。

我想我发现了一种更好,更优雅的方法,可以通过创建自己的自定义分页器来获得与以前使用旧的Paginated Serializer类类似的行为。

这是一个自定义分页器类。我重载了响应和下一页方法以获得想要的结果(即,?page=2而不是完整的URL)。

from rest_framework.response import Response
from rest_framework.utils.urls import replace_query_param

class CustomCoursePaginator(pagination.PageNumberPagination):
    def get_paginated_response(self, data):
        return Response({'count': self.page.paginator.count,
                         'next': self.get_next_link(),
                         'prevIoUs': self.get_prevIoUs_link(),
                         'courses': data})

    def get_next_link(self):
        if not self.page.has_next():
            return None
        page_number = self.page.next_page_number()
        return replace_query_param('', self.page_query_param, page_number)

    def get_prevIoUs_link(self):
        if not self.page.has_prevIoUs():
            return None
        page_number = self.page.prevIoUs_page_number()
        return replace_query_param('', self.page_query_param, page_number)

然后,我的课程视图与您的实现非常相似,只是这次使用“自定义分页器。

class CourseListView(AuthView):
    def get(self, request, format=None):
        """
        Returns a JSON response with a listing of course objects
        """
        courses = Course.objects.order_by('name').all()
        paginator = CustomCoursePaginator()
        result_page = paginator.paginate_queryset(courses, request)
        serializer = CourseSerializer(result_page, many=True)
        return paginator.get_paginated_response(serializer.data)

现在,我得到了想要的结果。

{
    "count": 384,
    "next": "?page=3",
    "prevIoUs": "?page=1",
    "courses": []
}

对于Browsable API,我仍然不确定(我不使用drf的此功能)。我认为您也可以为此创建自己的自定义类。我希望这有帮助!

Go 2022/1/1 18:43:32 有355人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶