Python/Django

[Django] Pagination 방법 비교 (Feat. Django, DRF)

yubi5050 2022. 11. 10. 06:14

Pagination이란?

Pagination 이란 한번에 많은 데이터를 받기 힘든 경우, 특정 구역을 나눠서 받는 방법

Django에서는 Pagination을 구현하기 위한 여러 모듈들이 존재하는데, 향후 Pagaintation 구현시 의사 결정을 빠르게 할 수 있도록, 각 방법을 비교 해보며 특징을 정리 해놓으려고 한다.

 

👉 Pagination 의 큰 갈래 (방향성)

Pagination 방법에는 여러 종류가 있겠지만 크게 3가지로 나뉘는 걸로 보이며, 1), 2) 의 경우 많이 쓰이는 대중적인 방법으로 선호됩니다. 3) 의 경우에도 

  • 1) 페이지 번호 기반 : 미리 페이지 크기(page_size)를 정하고, 페이지 번호(page_num)를 요청받아 조회 응답 방법
  • 2) 특정 지점 부터 특정 갯수 기반 : 특정 지점(offset) 부터 특정 데이터 갯수(limit)을 정해서 가져오는 방법
  • 3) 특정 데이터를 가리키는 커서 기반 : 특정 데이터의 PK(id) 값(Cursor)로 이전/다음 데이터를 조회하는 방법 

 

👉 Django/DRF에서 Pagination을 구현하는 4가지 방법  (모듈 중심)

  • Django - Paginator
  • DRF - PageNumberPagination
  • DRF - LimitOffsetPagination
  • DRF - CursorPagination

 

Django - Paginator

👉 Django - Paginator 특징

  • 페이지 번호 기반의 페이지네이션 방식 (페이지 번호, 페이지 크기)
  • 구현이 굉장히 간단하고, Django-template 활용시 보다 적합
  • Django-template에서 활용 가능한 페이징 객체의 다양한 속성, 메소드 존재
    - 속성 : 전체 갯수 (count) / 페이지 총 갯수 (num_pages)
    - 메소드 : 이전 페이지 유무 (has_previous) / 다음 페이지 번호 (next_page_number)
  • Django의 Paginator로 해당 필요 레코드만 로드
  • EmptyPage, PageNotAnInteger 등 예외 모듈 제공

 

👉 Django - Paginator 구현 예제

링크 :  https://yubi5050.tistory.com/151

 

[Django] Django Pagination (by. Django Paginator)

Django에서 게시판을 만드는 방법은 크게 아래 두가지 방향으로 구현이 가능하다. Django의 Paginator (django.core.paginator import Paginator) DRF(Django Rest Framework)의 Pagination(rest_frameowork.pagination) 두 방식은 각

yubi5050.tistory.com

 

DRF - PageNumberPagination

👉 DRF - PageNumberPagination 특징

  • 페이지 번호 기반의 페이지네이션 방식 (페이지 번호, 페이지 크기)
  • Client에게 page number를 Params로 받아, 해당 페이지 데이터 return
  • 기본적으로 count(전체 항목 갯수), next(다음 페이지 링크), previous(이전 페이지 링크) 값 들을 자동 반환

 

👉 DRF - PageNumberPagination 구현 예제

링크 : https://yubi5050.tistory.com/211

 

[Django] DRF Pagination (by. PageNumberPagination)

Django에서 게시판을 만드는 방법은 크게 아래 두가지 방향으로 구현이 가능하다. Django의 Paginator (django.core.paginator import Paginator) DRF(Django Rest Framework)의 Pagination(rest_frameowork.pagination) 두 방식은 각

yubi5050.tistory.com

 

DRF - LimitOffsetPagination

👉 DRF - LimitOffsetPagination 특징

  • 특정 지점 (offset) 부터 특정 갯수 (limit) 기반의 페이지네이션 방식 (사실 상 limit은 page_size와 유사)
  • Client에게 offset과 limit을 모두 Params로 받아, 해당 범위의 데이터를 return
  • 기본적으로 count (전체 항목 갯수), next(다음 페이지 링크), previous(이전 페이지 링크) 값 들을 자동 반환 
  • 페이지를 Parsing 하는 자유도가 PageNumberPagination에 비해 비교적 높음

 

👉 DRF - LimitOffsetPagination 구현 예제

링크 : https://yubi5050.tistory.com/212

 

[Django] DRF Pagination (by. LimitOffsetPagination)

Django에서 게시판을 만드는 방법은 크게 아래 두가지 방향으로 구현이 가능하다. Django의 Paginator (django.core.paginator import Paginator) DRF(Django Rest Framework)의 Pagination(rest_frameowork.pagination) 두 방식은 각

yubi5050.tistory.com

 

DRF - CursorPagination

👉 DRF - CursorPagination 특징

  • 특정 데이터를 가리키는 커서 기반의 페이지네이션 방식 (커서값, 페이지 크기)
  • Client에게 cursor 값을 Params로 받아, 해당 cursor부터 고정된 페이지 크기 만큼의 데이터 return
  • 기본적으로 next(다음 페이지 링크), previous(이전 페이지 링크) 값 들을 자동 반환
  • (차별점) 마지막 데이터(객체)에 대한 커서 값을 기억
  • (차별점) 기본적으로 CRUD 가 빈번하게 이루어지는 경우에 적합
  • (차별점) 전체 Count 값 반환 X => Counting 계산 시간 없음

 

👉 CursorPagination의 Pagenumber, LimitOffset 방법과의 차이점

중간에 데이터가 추가되는 (Writing 이벤트가 빈번한) 경우에 대해서 비교

 

1) Limit/Offset이나 PageNumber 방법

  • 중간에 데이터가 추가 되면, 페이지를 다시 계산하고 분리하거나 offset 위치를 다시 계산하는 작업 필요
  • 이렇게 데이터가 빈번하게 추가되는 경우 테이블 Full Scan에 대한 부담이 큼
  • pagination navigation 구현 시 주로 사용 가능

 

2) Cursor 기반 방법

  • 중간에 데이터가 추가 되어도 , 마지막 객체를 바탕으로 다음 데이터들을 찾기 때문에 FullScan을 하지 않아 부담이 적고, 다음 페이지네이션 조회시에도 값이 누락되지 않음
  • 해당 방법으로는 전체 페이지 갯수를 조회할 수 없어, pagination navigation을 구현이 불가능하여 주로 드래그 액션으로 다음 페이지를 탐색

 

👉 DRF - CursorPagination 구현 예제

링크 : https://yubi5050.tistory.com/213

 

[Django] DRF Pagination (by. CursorPagination)

Django에서 게시판을 만드는 방법은 크게 아래 두가지 방향으로 구현이 가능하다. Django의 Paginator (django.core.paginator import Paginator) DRF(Django Rest Framework)의 Pagination(rest_frameowork.pagination) 두 방식은 각

yubi5050.tistory.com

 

 

Pagination - API & Response 형태 비교

  특징 호출 API 결과 JSON
Django
Paginator
결과값만 리턴됨 /page?page=1 [
    {
        "id": 1,
        "title": "aaa",
        "content": "aaa",
    },
     ....

]
DRF
PageNumber-
Pagination
전체 데이터 갯수
이전/다음 페이지 URL
결과 값
/page?page=2 {
    "count": 8,
    "next": "/page/?page=3",  or
    "previous": "page/?page=2",  or
    "results": [{
            "id": 4,
            "title": "ddd",
            "content": "ddd"
        },]
       ....

}
DRF
LimitOffset-
Pagination
전체 데이터 갯수
이전/다음 limit의 URL
결과 값
/page?limit=4&offset=2 {
    "count": 8,
    "next": "page/?limit=4&offset=6",
    "previous": "page/?limit=4&offset=6",
    "results": [{
            "id": 4,
            "title": "ddd",
            "content": "ddd"
        },]
       ....
}
DRF
Cursor-
Pagination
이전/다음 항목 URL
결과 값
/page/?cursor=
/page/?cursor=cD1mZ
{
    "next": "/page/?cursor=cD1qa",
    "previous": /page/?cursor=cj0xJ",
    "results": [
        {
            "id": 5,
            "title": "ggg",
            "content": "ggg"
        },]
       ....
    ]
}

 

참고 문헌