Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django Rest Framework 3.1中断分页。分页序列化程序_Python_Django_Pagination_Django Rest Framework_Django Pagination - Fatal编程技术网

Python Django Rest Framework 3.1中断分页。分页序列化程序

Python Django Rest Framework 3.1中断分页。分页序列化程序,python,django,pagination,django-rest-framework,django-pagination,Python,Django,Pagination,Django Rest Framework,Django Pagination,我刚刚更新到Django Rest Framework 3.1,似乎一切都糟透了 在我的serializers.py中,我有以下代码: class TaskSerializer(serializers.ModelSerializer): class Meta: model = task exclude = ('key', ...) class PaginatedTaskSerializer(pagination.PaginationSerializer): cl

我刚刚更新到Django Rest Framework 3.1,似乎一切都糟透了

在我的
serializers.py中,我有以下代码:

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
    model = task
    exclude = ('key', ...)

class PaginatedTaskSerializer(pagination.PaginationSerializer):
    class Meta:
        object_serializer_class = TaskSerializer
这一切都很顺利。现在随着3.1的发布,我找不到如何做同样事情的例子,因为
分页序列化器
已经不存在了。
我曾尝试将
PageNumberPagination
子类化,并使用其默认的
paginate\u queryset
get\u paginated\u response
方法,但我无法再将其结果序列化

换句话说,我的问题是我不能再这样做了:

class Meta:
    object_serializer_class = TaskSerializer
有什么想法吗


提前感谢

我不确定这是否是完全正确的方法,但它适合我的需要。它使用Django Paginator和自定义序列化程序

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}
下面是我的视图类,它检索要序列化的对象

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)
这里是使用我的课程序列化程序的黑客组合序列化程序

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}
这给了我一个类似于老paginator给出的行为的结果

{
    "previous": 1,
    "next": 3,
    "courses": [...],
    "count": 384
}
我希望这有帮助。我仍然认为有一种更好的方法可以使用新的API来实现这一点,但它只是没有很好的文档记录。如果我想得更多,我会编辑我的帖子

编辑 我想我已经找到了一种更好、更优雅的方法,除了创建自己的定制分页器,以获得与旧分页序列化器类类似的行为

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

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

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": []
}
我仍然不确定这对于可浏览的API是如何工作的(我不使用drf的这个特性)。我认为您也可以为此创建自己的自定义类。我希望这有帮助

我想我已经明白了(至少在大部分情况下):

我们从一开始就应该使用的是:

只需使用内置分页器并将
views.py
更改为:

from rest_framework.pagination import PageNumberPagination

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 = PageNumberPagination()
        # From the docs:
        # The paginate_queryset method is passed the initial queryset 
        # and should return an iterable object that contains only the 
        # data in the requested page.
        result_page = paginator.paginate_queryset(courses, request)
        # Now we just have to serialize the data just like you suggested.
        serializer = CourseSerializer(result_page, many=True)
        # From the docs:
        # The get_paginated_response method is passed the serialized page 
        # data and should return a Response instance.
        return paginator.get_paginated_response(serializer.data)
对于所需的页面大小,只需在
设置.py
中设置
页面大小:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 15
}
您现在应该已经完全设置好响应主体中的所有选项(count、next和back链接),就像更新之前一样

然而,还有一件事仍然困扰着我:我们也应该能够得到新的,因为某些原因,目前还缺少


我当然可以在这方面多提几点建议……

我意识到这篇文章发表已经一年多了,但希望这能帮助其他人。对我类似问题的回答是我的解决方案。我使用的是DRF 3.2.3

看到它是如何实现的,我找到了在可见API中获得分页+控件所需的解决方案


我刚刚遇到了完全相同的问题。我决定升级我所有的软件包,这是唯一一个坏掉的东西。我希望这个问题能得到回答,因为我也没有发现任何东西。“我刚刚更新到Django Rest Framework 3.1,似乎一切都乱套了。”哈哈,是的。你的解决方案有效。它还不是最优的,因为我们无法在可浏览的API上获得分页链接(分页超链接也消失了),但目前它是唯一有效的。我们现在应该很接近了。如果你有更好的建议,请告诉我,否则我会在几天后接受你的回答。再次感谢。这也是正确的。我们现在几乎可以做任何事了。。!我相信解决方案的关键在于如何用一个简单的构造函数替换
class Meta:object\u serializer\u class=CourseSerializer
。超过这一点,我们可以让我们的想象力接管。不管怎样,我更愿意坚持默认值,但既然你给了我“钥匙”,我就接受你的答案。谢谢,哇。真的那么简单吗?他们应该用一个例子来更新文档。至于HTML链接,我不知道,我从来没有真正使用过可浏览的API.cool!这个解决方案节省了我很多时间来检查他们的源代码。我希望他们尽快制作文档。@hauding:制作您希望在世界上看到的文档!它是开源的,文档是一种很好的回馈方式。我检查了一下,光标分页的效果也一样。事实上,DRFv3.x分页是一个巨大的改进,可以直接使用。只是用法没有记录在案。因为我找不到HTML分页控件,所以找到了这个答案。如果覆盖它,则需要在
paginate\u queryset中设置
self.display\u page\u controls=True