search room 기능을 한 번 구현을 위한 몇가지 작업을 해볼게요.
왜냐하면 매우 구체적으로 우리가 필요한 로직 구현을 직관적으로 파악하기 위해서조.
일단 url 맵핑을 해줄게요.
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,를 넣어도 각 페이지에 맞는 정보가 나타나요.
여기서는 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와 기능을 확인할 수 있다는 장점이 있조.
잘보면 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)