【问题标题】:DRF: Pagination without querysetDRF:没有查询集的分页
【发布时间】:2016-11-12 01:44:12
【问题描述】:

我试图在我的案例中使用 Django Rest Framework 的分页机制,但没有成功。

class TransactionView(viewsets.ViewSet):

    serializer_class = TransactionSerializer

    def list(self, request):
        # fetching data from external API...

        serializer = self.serializer_class(data=list_of_json, many=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors) 


class TransactionSerializer(serializers.Serializer):
    # Serializer (transaction's) fields ...

    def create(self, validated_data):
        return APITransaction(**validated_data) 


class APITransaction(object):

    def __init__(self, arg1, arg2, ...):
        self.arg1 = arg1 
        ... 

问题是注册pagination_class(就像我为模型表示的其余资源所做的那样)不起作用,因为数据是动态创建/获取的,因此我没有有一个模型/查询集。

关于如何使用 DRF 的分页机制有什么想法吗?

【问题讨论】:

  • 你好,你是怎么解决的?您是否按照@Linovia 的回复并实现了自己的分页类?
  • 我没有时间在这里遵循最佳实践道路,所以我创建了一个函数,使用 django.core.paginator 手动构建响应以对 list_of_jsons 进行分页并使用 @ 构建 dict 987654326@ 我以return JsonResponse(the_dict, status=200, safe=False) 返回。我将四处寻找实际代码并提交新答案

标签: django-rest-framework


【解决方案1】:

这是我最终为此类事情创建并在本地使用的类。 (感谢上面的 stelios 提供初步线索。)当然“数据”的内容必须是 JSONable。

from typing import List, Any
from collections import OrderedDict
from django.core.paginator import Paginator
from django.http.response import JsonResponse
from rest_framework.request import Request

class ListPaginator:
    def __init__(self, request: Request):
        # Hidden HtmlRequest properties/methods found in Request.
        self._url_scheme = request.scheme
        self._host = request.get_host()
        self._path_info = request.path_info

    def paginate_list(self, data: List[Any], page_size: int, page_number: int) -> JsonResponse:
        paginator = Paginator(data, page_size)
        page = paginator.page(page_number)

        previous_url = None
        next_url = None
        if self._host and self._path_info:
            if page.has_previous():
                previous_url = '{}://{}{}?limit={}&page={}'.format(self._url_scheme, self._host, self._path_info, page_size, page.previous_page_number())
            if page.has_next():
                next_url = '{}://{}{}?limit={}&page={}'.format(self._url_scheme, self._host, self._path_info, page_size, page.next_page_number())

        response_dict = OrderedDict([
            ('count', len(data)),
            ('next', next_url),
            ('previous', previous_url),
            ('results', page.object_list)
        ])
        return JsonResponse(response_dict, status=200, safe=False)

【讨论】:

    【解决方案2】:

    您不能重复使用现有 DRF 的分页,因为它们应该与查询集一起使用。 但是,您可以通过继承 BasePagination 来创建自己的类,尽管我自己没有这样做。

    【讨论】:

    • 不要认为这有帮助 - BasePagination 从根本上讲也是关于“paginate_queryset”方法。我还想对列表进行分页;我将在上面尝试 stelios 的方法。
    • 你说得对,这没有帮助。我一开始就应该结束这个问题,因为它太宽泛了。
    猜你喜欢
    • 1970-01-01
    • 2012-01-13
    • 2021-05-02
    • 1970-01-01
    • 2010-10-23
    • 2011-03-14
    • 2022-09-27
    • 2021-12-14
    相关资源
    最近更新 更多