[drf]airbnb-api -15 Manual Pagination

Hyeseong·2021년 3월 28일
0
post-thumbnail

search room 기능을 한 번 구현을 위한 몇가지 작업을 해볼게요.

페이지 네이션

왜냐하면 매우 구체적으로 우리가 필요한 로직 구현을 직관적으로 파악하기 위해서조.

일단 url 맵핑을 해줄게요.

rooms/urls.py

urlpatterns = [
     path('', views.RoomsView.as_view()),
     path('search', views.room_search),
     path('<int:pk>/', views.RoomView.as_view()),
]

아래 endpoint를 보면 페이지 네이션이 없어요. 왜냐하면 CBV에서 주는 페이지네이션을 이용하지 않았어요.

from rest_framework.decorators import api_view
from rest_framework.pagination import PageNumberPagination
# 생략

...
...
...

@api_view(["GET"])
def room_search(request):
    return Response

쭉쭉 이어 나가볼게요.
PageNumberPagination 클래스가 핵심인데요 일단 임포트 해주고 이를 이용해서 paginator인스턴스를 만들어 줄게요.
paginate_queryset()ㅁㅔ서드를 이용해서 첫번째는 쿼리셋을 받고 두번째는 reqeust객체를 받아서 변수 results를 만들어 줍니당! 그리고 RoomSerializer()의 첫번째 클래스 매개변수에 results를 넣어주고 나머지 작업은 기존 시리얼라이저 클래스를 만들때 했던것처럭 작업을 해줄게요.

from rest_framework.decorators import api_view
from rest_framework.pagination import PageNumberPagination



class RoomsView(APIView):
    def get(self, request):
	paginator = PageNumberPagination()
        paginator.page_size = 20
        rooms = Room.objects.all()
        results = paginator.paginate_queryset(rooms, request)
        serializer = RoomSerializer(results, many=True).data
        return Resonse(serializer)


@api_view(["GET"])
def room_search(request):
    return Response

그럼 확인을 땅~! 하고 해보면 정상적으로 ?page=1이라고 주소창에 뜨는게 보이고 2,3,4,를 넣어도 각 페이지에 맞는 정보가 나타나요.

search API 페이지 네이션 만들기

여기서는 room인스턴스를 모두 all()로 받아 왔는데 조건에 맞는 방을 찾아야 하기에 filter()로 사용할게요.

return 키워드에 넘겨주는 부분을 보면 get_paginated_response()라는 점이 눈에 띄조?
이걸 사용하면 아래와 같이 2가지 특징을 구현 할 수 있어요.

  • 전체 게시물의 수
  • 페이지 숫자를 세는 기능
  • 이전 페이지, 다음 페이지 기능
from rest_framework.decorators import api_view
from rest_framework.pagination import PageNumberPagination



class RoomsView(APIView):
    def get(self, request):
	paginator = PageNumberPagination()
        paginator.page_size = 20
        rooms = Room.objects.all()
        results = paginator.paginate_queryset(rooms, request)
        serializer = RoomSerializer(results, many=True)
        return paginator.get_paginated_response(serializer.data)
...
...
...

@api_view(["GET"])
def room_search(request):
    paginator = PageNumberPagination()
    rooms = Room.objects.filter()
    results = paginator.paginate_queryset(rooms, request)
    serializer = RoomSerializer(results, many=True).data
    return paginator.get_paginated_response(serializer.data)

get_paginated_response() 메서드 사용시 얻을 수 있는게 count, next, previous와 같이 추가 적인 data와 기능을 확인할 수 있다는 장점이 있조.

OwnPagination

잘보면 PageNumberPagination클래스 2곳에서 중복되서 사용하고 있어요. 더군다나 page_size의 속성 역시도 그렇구요.

커스터 마이징 해봅시다.

from rest_framework.decorators import api_view
from rest_framework.pagination import PageNumberPagination



class OwnPagination(PageNumberPagination):
    page_size = 20
    

class RoomsView(APIView):
    def get(self, request):
        paginator = OwnPagination()
        rooms = Room.objects.all()
        results = paginator.paginate_queryset(rooms, request)
        serializer = RoomSerializer(results, many=True)
        return paginator.get_paginated_response(serializer.data)
...
...
...

@api_view(["GET"])
def room_search(request):
    paginator = OwnPagination()
    rooms = Room.objects.filter()
    results = paginator.paginate_queryset(rooms, request)
    serializer = RoomSerializer(results, many=True)
    return paginator.get_paginated_response(serializer.data)
profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글