프로그래밍

[DRF] 페이지네이션(Pagination) 본문

Python/Django REST Framework

[DRF] 페이지네이션(Pagination)

시케 2023. 11. 28. 14:45
728x90
반응형

2023.11.27.화

페이지네이션

Django REST Framework는 API 응답에서 결과를 페이지로 나누어 제공하는 기능이다
DRF에서는 limit/offset 페이지네이션, 커서 페이지네이션 등 다양한 페이지네이션 스타일을 지원한다
페이지네이션은 대량의 데이터를 처리하면서 효율적으로 리소스를 사용할 수 있도록 한다

 

PageNumberPagination(기본 페이지네이션)

가장 기본적인 방법으로 장고의 Paginator를 사용한다

 

[(페이지넘버 - 1) * 페이지사이즈:(페이지넘버 - 1) * 페이지사이즈 + 페이지사이즈]

형식으로 계산되며 SQL문은 다음과 같다

select * from article limit 10 offset 20

 

쿼리에서 limit는 페이지사이즈가 offset은 (페이지넘버 -1) * 페이지사이즈가 된다

 

offset이 limit의 배수로 설정된다

 

LimitOffsetPagination(무한 스크롤 페이지네이션)

PageNumberPagination과 거의 유사하지만 limit_query_param과 offset_query_param 을 사용해서 조회한다
PageNumberPagination과 같은 방법으로 데이터를 조회하며
쿼리에서 limit은 limit_query_param가 되고 offset은 offset_query_param 가 된다

파라미터로 받아오기 때문에 offset이 lilmit의 배수여야 하는 것은 아니다

CursorPagination(커서 페이지네이션)

Cursor Pagimation은 ordering 기준으로 페이지를 구하는 방식이다

인덱스가 적용된 값을 비교하기 때문에 테이블을 풀 스캔하지 않는다

 

id 값으로 데이터를 조회하기 때문에, 데이터 쓰기가 빈번한 테이블이여도 다음 페이지네이션 조회 시 값이 누락되지 않는다
단, 전체의 페이지 개수는 알 수 없다.

 

인코딩된 커서 쿼리 파라미터를 가지고있다.
http://127.0.0.1:8000/api/vi/app/post/?cursor=cD05OTQ% 처럼 인코딩된 쿼리 파라미터가 디코딩된 후 그에 맞는 sql 문을 작성한다

 

SELECT "app_post"."id", "app_post"."title" FROM "app_post" WHERE "app_post"."id" < 994 ORDER BY "app_post"."id" DESC 쿼리에 따라 ASC/DESC 와 ORDER_BY 절, WHERE절이 구성된다.
그 다음에 page_size 필드를 통해 LIMIT 된다.

 

장단점

PageNumberPagination과 LimitOffsetPagination은

유저가 페이지를 선택할 수 있으며 전체 페이지 수를 알 수 있다

 

단, offset 위치를 계산하고, 필요한 데이터를 찾을 때까지 테이블 전체를 스캔한다
∴ offset이 커질 수록 데이터베이스의 부하는 커진다

Pagination 적용

settings.py에서 기본적으로 사용할 페이지네이션을 설정할 수 있다

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

 

app 하위에 paginaton.py에서 페이지네이션을 설정 가능하다

from rest_framework.pagination import LimitOffsetPagination

class CustomLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 20				# 페이지당 기본 아이템 수
    limit_query_param = 'limit'		# 제한을 조절하는 쿼리 파라미터
    offset_query_param = 'offset'	# 오프셋을 조절하는 쿼리 파라미터
    max_limit = 100					# 허용된 최대 제한

    def get_paginated_response(self, data):
        return {
            'next': self.get_next_link(),
            'previous': self.get_previous_link(),
            'count': self.count,
            'results': data
        }

 

이 밖에도 커스텀하여 사용 또한 가능하다

 

 

 

 

 

 

728x90
반응형

'Python > Django REST Framework' 카테고리의 다른 글

[DRF] status  (0) 2023.11.29
[DRF] Response  (0) 2023.11.29
[DRF] APIView와 api_view  (1) 2023.11.29
[DRF] Serialize(직렬화)  (1) 2023.11.28
[DRF] Django REST Framework  (0) 2023.11.28
Comments