[Django] REST Framework를 이용한 페이징
간단한 블로그 같은 CRUD 앱을 만드려면 페이징 기능은 거의 필수라고 봐도 무방합니다.
Django의 REST Framework는 ListAPIView를 통해 이를 쉽게 구현할 수 있도록 여러가지 기능을 지원해주고 있습니다.
ListAPIView
클라이언트 측에서 데이터베이스의 내용을 불러오는 API 요청을 구현하려면 ListAPIView를 사용하면 편합니다.
from rest_framework.generics import ListAPIView
from .models import Post
from .serializers import PostSerializer
class PostListView(ListAPIView):
queryset = Post.objects.all().order_by('-created_at')
serializer_class = PostSerializer
GET 요청만 가능하며 읽기 전용으로만 동작합니다. 반환해줄 데이터는 queryset에, 사용할 serializer은 serializer_class에 각각 저장해 놓으면, 해당 view를 호출할 시에 ListAPIView에서 자동으로 queryset과 serializer_class 값을 참조하여 queryset의 값을 클라이언트에게 반환해줍니다. 예를 들면 게시글의 목록이 될 수가 있겠네요.
Pagination
ListAPIView에 pagination을 추가해서 queryset의 객체 수에 따라 페이지를 자동으로 나누고, 원하는 페이지만 반환하도록 구현할 수 있습니다.
from rest_framework.generics import ListAPIView
from .models import Post
from .serializers import PostSerializer
from rest_framework.pagination import PageNumberPagination
class StandardResultsSetPagination(PageNumberPagination):
page_size = 10
#한 페이지당 표시할 정보의 수
page_size_query_param = 'page_size'
max_page_size = 100
class PostListView(ListAPIView):
queryset = Post.objects.all().order_by('-created_at')
serializer_class = PostSerializer
pagination_class = StandardResultsSetPagination
이렇게 하면 view에서는 queryset의 객체의 수에 설정된 page_size만큼 나누어 자동으로 페이징을 해줍니다. StandardResultsSetPagination 클래스를 선언해서 page_size의 기본값 및 GET요청을 보낼때 페이지의 크기를 지칭할 변수의 이름을 설정할 수도 있습니다.
즉, 클라이언트 측에서 GET요청을 보낼때 url에 ?page=1&page_size=10 과 같이 보내면, 원하는 범위만큼 데이터를 반환해줍니다.
이때 반환되는 데이터는 다음과 같은 Json 형태를 갖습니다.
{
"count": 11,
"next": "http://localhost:8000/board/?page=2&page_size=10",
"previous": null,
"results": {(...), (...), (...), (...), (...), (...), (...), (...), (...), (...)},
}
count는 queryset에 담겨있던 모든 데이터의 갯수를 의미하며, 다음 페이지 혹은 이전 페이지에 접근할 수 있는 엔드포인트를 친절하게 next와 previous에 담아줍니다. (위와 같은 경우는 페이지 1번이므로 이전 페이지는 null)
마지막으로 해당 페이지에 담길 데이터들은 results에 담겨지는데, results의 각 객체는 serializers의 형태를 따라갑니다. 예를 들어 게시글 데이터라면 기본적인 id와 함께 제목, 내용, 작성자 등이 담길 수 있겠죠.
이렇게 반환된 데이터를 frontend측에서 잘 처리만 한다면 CRUD 앱을 만들때 쉽게 페이징을 적용할 수 있습니다.