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
DRF - PageNumberPagination
👉 DRF - PageNumberPagination 특징
- 페이지 번호 기반의 페이지네이션 방식 (페이지 번호, 페이지 크기)
- Client에게 page number를 Params로 받아, 해당 페이지 데이터 return
- 기본적으로 count(전체 항목 갯수), next(다음 페이지 링크), previous(이전 페이지 링크) 값 들을 자동 반환
👉 DRF - PageNumberPagination 구현 예제
링크 : https://yubi5050.tistory.com/211
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
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
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" },] .... ] } |
참고 문헌
- Django - 페이징네이션
- DRF - Pagination 공식 문서
- DRF - Pagination 적용하기
- DRF - Pagination : PageNumberPagination vs LimitOffsetPagination
- Django Pagination 종류, 차이점
'Python > Django' 카테고리의 다른 글
[Django] Django Model - Table Field, Relationship (1) | 2023.02.07 |
---|---|
[Django] 간단한 메일 전송 기능 구현 (by. Gmail ) (0) | 2022.11.18 |
[Django] Django Pagination (by. Django Paginator) (0) | 2022.11.10 |
[Django] Request 구조 분석 (with. DRF, Query-String vs Path-variables) (0) | 2022.08.22 |
[Django] Query Profiling Tool (3) - Silk (0) | 2022.08.12 |