我试图在我的案例中使用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的分页机制的任何想法?
答案 0 :(得分:2)
您无法重复使用现有DRF的分页,因为它们应该与查询集一起使用。
但是,您可以通过继承BasePagination
来推广自己的课程,但我还没有完成。
答案 1 :(得分:1)
这是我在本地为此类事情创建和使用的类。 (感谢上面的 stelios 提供了初步线索。)当然,“data”的内容必须是 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)