APIView
는 settings.py
의 DEFAULT_PAGINATION_CLASS
가 Django가 알아서 적용해주지 않아서 따로 구현하여 적용(이전 프로젝트를 참고)
class PaginationHandlerMixin(object):
@property
def paginator(self):
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator=None
else:
self._paginator=self.pagination_class()
else:
pass
return self._paginator
def paginate_queryset(self, queryset):
if self.paginator is None:
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
def get_paginated_response(self, data):
assert self.paginator is not None
return self.paginator.get_paginated_response(data)
래퍼런스는 각 카테고리 url이 나눠져 있지만 class를 여러개 만들 필요성을 느끼지 못해 get parameter로 받아서 그에 맞는 데이터를 가져오는 방식으로 구현하기로 했다.
class NewsListAPIView(APIView, PaginationHandlerMixin):
permission_classes = [IsAuthenticatedOrReadOnly]
pagination_class = NewsPagination
def get(self, request):
if request.GET.get("category") == "weekly":
news = (
News.objects.filter(Q(category="news") | Q(category="show") | Q(category="plus"))
.annotate(likes_count=Count("likes"))
.order_by("-likes_count")[:20]
)
elif request.GET.get("category") == "plus":
news = News.objects.filter(category="plus").order_by("-created_at")
elif request.GET.get("category") == "ask":
news = News.objects.filter(category="ask").order_by("-created_at")
elif request.GET.get("category") == "show":
news = News.objects.filter(category="show").order_by("-created_at")
elif request.GET.get("category") is None:
news = News.objects.all().order_by("-created_at")
page = self.paginate_queryset(news)
if page is not None:
serializer = self.get_paginated_response(
NewsSerializer(page, many=True).data
)
else:
serializer = NewsSerializer(news, many=True)
return Response(serializer.data)
pagination도 적용하여 구현