Глобальная пагинация не работает в проекте DRF
Я написал API на DRF, который возвращает список данных на основе определенных условий, но данные очень большие и глобальная пагинация к ним не применяется. В результате скорость работы замедляется, и поэтому данные не отображаются должным образом на одной странице.
Я добавил следующий код в файл settings.py:
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": 10
}
Это мой API:
class TeacherViewSet(ModelViewSet):
queryset = Teacher.objects.all()
serializer_class = serializers.TeacherSerializer
authentication_classes = [TokenAuthentication]
def list(self, request, *args, **kwargs):
response = []
for teacher in queryset:
name = Student.objects.filter(teacher=teacher).values("name")
res = {"name": name}
response.append(res)
return Response(response)
Есть ли что-то неправильное в моих действиях?
Поскольку вы переопределяете метод list
, вы отключаете функцию пагинации. Метод по умолчанию list
выглядит следующим образом:
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
Обратите внимание на методы paginate_queryset
и get_paginated_response
, которые выполняют пагинацию. Поэтому если вам нужно переопределить list
, вы должны включить и эти методы:
def list(self, request, *args, **kwargs):
response = []
queryset = self.filter_queryset(self.get_queryset())
queryset = self.paginate_queryset(queryset)
for teacher in queryset:
name = Student.objects.filter(teacher=teacher).values("name")
res = {"name": name}
response.append(res)
return self.get_paginated_response(response)
Не относится к исходному вопросу, но обратите внимание, что выполнение DB запроса внутри цикла считается плохой практикой и может повлиять на производительность вашего представления. Вместо выборки учеников для каждого учителя внутри цикла for используйте prefetch_related.