DRF | 페이지네이션

2022. 8. 30. 13:49·Django
반응형

이렇게 작성한 리뷰 리스트 뷰에 페이지네이션을 적용하려고 한다.

 

class ReviewListCreateAPIView(ListCreateAPIView):

    queryset = Review.objects.filter(is_active=True).order_by("-created_at")
    permission_classes = [AllowAny]  # 아직 작업중이기때문에 테스트를 위해 AllowAny로 설정

    def get_serializer_class(self):
        if self.request.method == "GET":
            return serializers.ReviewListSerializer
        if self.request.method == "POST":
            return serializers.ReviewCreateSerializer

    def get(self, request, *args, **kwargs):
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return super().post(request, *args, **kwargs)

직접 작성

프론트엔드에서 page키로 페이지 번호를 주기로 했다.

그래서 직접 limit을 설정하고 offset을 계산해서 슬라이싱하는 방법으로 작성했다.

(데이터가 7개뿐이라 확인을 위해 3개씩....)

 

class ReviewListCreateAPIView(ListCreateAPIView):

    permission_classes = [AllowAny]

    def get_queryset(self):
        page = int(self.request.query_params.get("page", 1))
        limit = 3
        offset = (page - 1) * limit
        queryset = Review.objects.filter(is_active=True).order_by("-created_at")[
            offset : offset + limit
        ]
        return queryset

    def get_serializer_class(self):
        if self.request.method == "GET":
            return serializers.ReviewListSerializer
        if self.request.method == "POST":
            return serializers.ReviewCreateSerializer

    def get(self, request, *args, **kwargs):
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return super().post(request, *args, **kwargs)

 

DRF Pagination

장고 REST framework에서는 페이지네이션을 쉽게 사용할 수 있는 기능을 제공해준다.

 

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 100
}

 

이런식으로 정의해주면 된다.

DEFAULT_PAGINATION_CLASS'와 'PAGE_SIZE'의 기본값은 None이다.

 

이 기능을 이용해서 페이지 번호 기반 페이지네이션을 적용하려면

요청은 이렇게 쿼리파라미터에 page키로 페이지 번호를 보내줘야 하고

 

GET https://api.example.org/accounts/?page=4

 

전역적으로 같은 페이지네이션 방식을 적용하려면 settings.py에 아래와 같이 넣어준다.

 

#settings.py
REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 3,
}

 

그리고 views의 코드는 페이지네이션이 없는 상태 그대로 두면(맨위 코드 그대로) 자동으로 DEFAULT_PAGINATION_CLASS에 따라 페이지 번호 기반으로 페이지네이션이 구현된다!

 

응답형태

응답의 형태는 자동으로 

 

HTTP 200 OK
{
    "count": 1023,
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}

 

이렇게 나오는데

총 개수, 다음경로, 이전경로가 자동으로 나오게 된다. 그리고 원래 결과가 results에 담겨서 나온다

 

그냥 슬라이싱했을때

 

[
    {},
    {},
    {},
    ...
]

 

drf의 페이지넘버페이지네이션 적용했을때

 

HTTP 200 OK
{
    "count": 7,
    "next": "http://localhost:8000/review/?page=2",
    "previous": null,
    "results": [
        {},
        {},
       …
    ]
}

 

 

 

참고

https://www.django-rest-framework.org/api-guide/pagination/

반응형
저작자표시 비영리 변경금지 (새창열림)

'Django' 카테고리의 다른 글

Django | 쿼리셋 내 객체 수  (0) 2022.09.22
Django | Error : you cannot alter to or from M2M fields, or add or remove through= on M2M fields  (0) 2022.08.30
Django | models : verbose_name  (0) 2022.08.20
Django | ORM : on_delete=models.CASCADE  (0) 2022.08.14
Django | 프로젝트 초기세팅  (0) 2022.07.16
'Django' 카테고리의 다른 글
  • Django | 쿼리셋 내 객체 수
  • Django | Error : you cannot alter to or from M2M fields, or add or remove through= on M2M fields
  • Django | models : verbose_name
  • Django | ORM : on_delete=models.CASCADE
이라후
이라후
  • 이라후
    화이팅
    이라후
  • 전체
    오늘
    어제
    • 분류 전체보기 (133)
      • TIL (23)
      • 기타 (26)
      • Python (14)
      • Django (10)
      • JavaScript (8)
      • git & GitHub (8)
      • Web (10)
      • Go (3)
      • wecode (31)
  • 반응형
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
이라후
DRF | 페이지네이션
상단으로

티스토리툴바