当前位置: 首页 > 面试题库 >

Django Rest Framework 3.1打破了分页.PaginationSerializer

储法
2023-03-14
问题内容

我刚刚更新到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的发布,我不再找到有关如何执行相同操作的示例,因为该示例PaginationSerializer不再存在。我尝试子类化PageNumberPagination并使用其默认值paginate_querysetget_paginated_response方法,但无法再序列化其结果。

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

class Meta:
    object_serializer_class = TaskSerializer

有任何想法吗?

提前致谢


问题答案:

我不确定这是否是完全正确的方法,但是它可以满足我的需求。它使用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的此功能)。我认为您也可以为此创建自己的自定义类。我希望这有帮助!



 类似资料:
  • 如果是这样,那怎么可能是封装呢?变量仍然是公共的。将其声明为private将迫使我创建一个setter和getter来获取变量,因为private可见性修饰符。 我将其与Java进行比较,后者通常将成员变量作为private以及每个成员变量的public setter和getter。

  • 问题内容: 我的数据库中的名称记录偶尔包含撇号,例如,而我刚刚用PHP编写了一个查询脚本,该脚本捕获了该字段并将其粘贴到带有通常名称的select语句中,某些餐馆名称中的撇号使Love Train脱轨。 如何避免这种情况发生? 答案 -使用与通过PHP将它们插入数据库时​​使用的相同技术。 反驳 -然后我遇到了同样的问题,然后直接使用PHPMyAdmin作弊并输入了麻烦的问题,但这再也不能忽略了。

  • null 04:52:42.738警告:没有为分析源文件提供依赖项的字节码,最终可能会得到不太精确的结果。可以使用sonar.java.Libraries属性提供字节码

  • 我试图使用注释处理器来生成特定工厂接口的实现。这些接口如下所示: 和 注释处理器正在做正确的事情,并为每个匹配的类生成一个工厂,该工厂用相应的注释进行注释。 注释处理器的输出如下所示: 以及相应的其他类: 但是不能编译TestViewImFactory。错误消息是: “类'TestViewImplFactory'必须声明为抽象或在'ViewFactory'中实现抽象方法创建” Java说,以下是正

  • 我试图制作一个简单的基于文本的游戏,在这个游戏中,你在一个由“#”组成的网格周围移动“@”,并试图找到出口。我已经改变了代码,使我更容易使网格更大或更小,而无需添加或删除大量代码,它一直给我这样的输出: 我不知道这是怎么回事!只有一个“@”应该出现:(我只是python的新手,所以如果您有任何改进的建议,请不要犹豫,然后发布它们!提前感谢,

  • 我有一个困难的时间设置我的WP。 我的结构peramink是这样的: 游戏/分类slug/postname 为此,我使用了UltimateCMS插件。 我已经使我的自定义帖子类型名称"游戏"谁是这样配置的: 重写:真,弹头:游戏/%游戏%,宽度tront:真,提要:真,页面:真,层次:假 我的分类法名为“games”,配置如下: 分层:false,重写:true,段塞:%游戏%,宽度tront:f

  • 问题内容: 我正在尝试让Google Chrome浏览器执行分页符。 通过一堆在chrome中有效的网站已经告诉我,但即使有一个非常简单的示例,我似乎也无法使其正常工作。使用chrome打印时,有什么方法可以强制分页? 问题答案: 我已经在包括Chrome在内的所有主要浏览器中成功使用了以下方法: 这是一个简化的示例。在实际代码中,每个页面div包含更多元素。

  • 我有一个gradle文件,它在gradle的一些古老版本中工作,但我想升级到Gradle5.0。不幸的是,它使用了ivy而不是maven来发布它的JAR。我把它简化为一个简单的测试用例。 在4.7中可以正常工作。它发布主jar和源jar,并添加依赖项。 如果切换到4.8,它会中断,它只发布源jar,主jar和依赖项都丢失了。 如果切换到4.8并注释掉配置位,它将再次发布主jar和依赖项。 也许有一