수학과의 좌충우돌 프로그래밍

[Django] DRF Pagination 본문

웹프로그래밍/DRF

[Django] DRF Pagination

ssung.k 2019. 12. 30. 00:29

실제 서비스의 경우에는 레코드의 개수가 많을 것이고 이 경우 하나의 API 요청으로 모든 레코드를 받는 것은 오랜 시간이 걸리게 됩니다. 따라서 이런 경우 페이지를 나눠서 요청을 해야합니다. 다행히도 DRF 에서는 이러한 pagination 기능을 제공하고 있습니다.

PageNumberPagination 과 LimitOffsetPagination

pagination 을 하는데는 크게 두 가지 방법이 있습니다.

두 방법 모두 url 의 get parameter 를 이용하여 이를 지원해줍니다.

각각에 대해 알아보도록 하겠습니다.

  • PageNumberPagination

    • page : 몇 번째 페이지인지 표시해줍니다. 페이지는 1부터 시작합니다.
    • page_size : 한 페이지에 몇 개의 레코드를 보여줄지 표시해줍니다.
  • LimitOffsetPagination

    • offset : 몇 번째 레코드부터 보여줄 지 설정해줍니다. 설정하지 않을 시 첫 번째 레코드 부터 보여줍니다.
    • limit : 몇 개의 레코드를 보여줄 지 설정합니다.
    • offset 번째 레코드부터 offset+limit-1 번째 레코드까지 보여줍니다.

 

전역 설정을 통해 Pagination

PageNumberPagination 이 더 사용 빈도가 많으니 이를 적용해보도록 하겠습니다.

settings 에서 기본적인 설정을 해줍니다.

어느 pagination을 할 지 결정하고, 그에 대한 parameter 값을 지정해줍니다.

# settings.py

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 3, 
}

 

그 결과 평상시와 좀 다른 응답이 왔습니다.

  • count : 전체 레코드의 수를 나타냅니다.
  • next, previous : 다음 페이지와 이전 페이지의 url 을 나타냅니다.
  • results : 이번 페이지에서의 레코드들을 나타냅니다.
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 5,
    "next": "http://localhost:8000/post/?page=2",
    "previous": null,
    "results": [
        {
            "id": 1,
            "title": "첫번째 제목",
            "content": "첫번째 내용",
            "is_public": false,
            "create_at": "2019-12-29T12:14:20.969581Z",
            "update_at": "2019-12-29T12:22:22.953888Z",
            "author": 1
        },
        {
            "id": 2,
            "title": "두번째 제목",
            "content": "두번째 내용",
            "is_public": false,
            "create_at": "2019-12-29T12:14:35.953629Z",
            "update_at": "2019-12-29T12:14:35.953671Z",
            "author": 1
        },
        {
            "id": 3,
            "title": "세번째 제목",
            "content": "세번째 내용",
            "is_public": false,
            "create_at": "2019-12-29T15:00:38.367163Z",
            "update_at": "2019-12-29T15:00:38.367214Z",
            "author": 1
        }
    ]
}

 

개별적으로 다른 Pagination

settings 를 통해서 설정을 해주게 되면 모든 view 에 대해서 같은 설정을 할 수 밖에 없습니다. 따라서 각각 개별적으로 설정하는 방법에 대해 알아보도록 하겠습니다. 이를 통해 전역적으로 설정되어있는 값을 덮어쓸 수도 있습니다.

우선 새로운 파일을 만들어 pagination 설정을 해줍니다.

PageNumberPagination을 상속받고 page_size 도 설정해주었습니다.

# pagination.py

from rest_framework.pagination import PageNumberPagination

class PostPageNumberPagination(PageNumberPagination):
    page_size = 2

 

view 에서는 이를 지정만 해주면 됩니다.

from rest_framework.viewsets import ModelViewSet
from rest_framework.filters import SearchFilter
from .models import Post
from .serializers import PostSerializer
from .pagination import PostPageNumberPagination


class PostViewSet(ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    pagination_class = PostPageNumberPagination

 

개별적으로 사용해야하는 경우가 있더라도 우선 settings 에서 전체적인 값을 설정한 후 개별 설정을 하는 것을 추천드립니다.

Comments