Я не уверен, если это совершенно правильный способ сделать это, но это работает для моих потребностей. Он использует 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)
Вот взломан вместе Serializer, который использует мой сериалайзер курс.
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, но он просто не документирован. Если я что-нибудь придумаю, я отредактирую свой пост.
EDIT
Я думаю, что я нашел лучший, более изящный способ сделать это беку создать свой собственный Paginator, чтобы получить поведение, как я использовал, чтобы получить со старым классом Постраничного Serializer.
Это настраиваемый класс paginator. Я перегрузил методы ответа и следующей страницы, чтобы получить результат, который я хочу (т. Е. ?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 (я не пользователь эта особенность ФПИ). Я думаю, вы также можете создать свой собственный собственный класс для этого. Надеюсь, это поможет!
Я только столкнулся с этой проблемой. Я решил обновить все свои пакеты, и это было единственное, что сломалось. Надеюсь, на это на него назовут, потому что я тоже ничего не нашел. – Brobin
«Я только что обновился до Django Rest Framework 3.1, и кажется, что весь ад сломался». Лол. – jmoz