DRF에서 제공하는 pagination들 (링크)
PageNumberPagination -> 가장 많이 사용!
LimitOffsetPagination
CursorPagination
코드
views.py
# pagination overriding
class PostPageNumberPagination(PageNumberPagination):
page_size = 3
# page_size_query_param = 'page_size'
# max_page_size = 1000
class PostListAPIView(ListAPIView):
queryset = Post.objects.all()
serializer_class = PostListSerializer
pagination_class = PostPageNumberPagination
page_size = 3
: 한 페이지 당 항목 개수
pagination_class = PostPageNumberPagination
: 오버라이딩한 페이지네이션 클래스를 해당 뷰의 페이지네이션 클래스로 적용
결과
pagination이 적용된 결과로 count
, next
, previous
, result
키가 등장함
key 이름 변경 필요!(PostList
, pageCnt
, curPage
) -> PageNumberPagination 클래스 확인 후 수정(override)
paginate_queryset
: 초기에 테이블로부터 데이터를 가져와서 지정된 개수(=3개씩)만큼 페이지를 구분
get_paginated_response
: 페이지로 구분된 항목들을 응답에 사용
여기서 출력 항목들을 정해주고 있었음!
이 메서드를 가져와서 오버라이딩함
# pagination overriding
class PostPageNumberPagination(PageNumberPagination):
page_size = 3 # 한 페이지 당 항목 개수
# page_size_query_param = 'page_size'
# max_page_size = 1000
def get_paginated_response(self, data):
return Response(OrderedDict([
('postList', data),
('pageCnt', self.page.paginator.count),
('curPage', self.page.paginator.count)
]))
class PostListAPIView(ListAPIView):
queryset = Post.objects.all()
serializer_class = PostListSerializer
pagination_class = PostPageNumberPagination
self.page.paginator.count
: count 값은 '총 항목의 개수'임!결과
Django Docs
확인Django Docs
Pagination - Using Django
: Pagination의 개념 설명
Paginator - API Reference
✔ : Paginator의 속성이나 메서드를 설명하는 페이지 (링크)
Paginator.per_page : DRF의 page_size와 동일
Paginator.count : 총 항목의 개수
Paginator.num_pages✔ : 페이지의 개수
Page.number✔ : 현재 페이지의 번호
이 항목들을 소스코드에 반영!
# pagination overriding
class PostPageNumberPagination(PageNumberPagination):
page_size = 3 # 한 페이지 당 항목 개수
# page_size_query_param = 'page_size'
# max_page_size = 1000
def get_paginated_response(self, data):
return Response(OrderedDict([
('postList', data),
('pageCnt', self.page.paginator.num_pages),
('curPage', self.page.number),
]))
class PostListAPIView(ListAPIView):
queryset = Post.objects.all()
serializer_class = PostListSerializer
pagination_class = PostPageNumberPagination
반영된 결과
카테고리가 pk로 나오는 이유
>>> from api2.serializers import *
>>> PostListSerializer()
PostListSerializer():
id = IntegerField(label='ID', read_only=True)
title = CharField(label='TITLE', max_length=50)
image = ImageField(allow_null=True, label='IMAGE', max_length=100, required=False)
like = IntegerField(label='LIKE', required=False)
category = PrimaryKeyRelatedField(allow_null=True, queryset=Category.objects.all(), required=False)
PrimaryKeyRelatedField
로 정의되어 있기 때문에 pk로 표현되는 것!⭐⭐⭐ForeignKey
이기 때문에, DRF에서 자동으로 PrimaryKeyRelatedField
로 잡은 것!.
을 통해서 특정 속성을 가져올 땐, 가져오려는 속성을 source=
인자로 넣어줌!⭐⭐⭐ → serializer 오버라이딩source='category.name'
serializer 오버라이딩⭐⭐⭐
class PostListSerializer(serializers.ModelSerializer):
class Meta:
model = Post
# fields = '__all__'
fields = ['id', 'title', 'image', 'like', 'category']
class PostListSerializer(serializers.ModelSerializer):
category = serializers.CharField(source='category.name') ⭐
class Meta:
model = Post
# fields = '__all__'
fields = ['id', 'title', 'image', 'like', 'category']
rest_framework/fields.py
to_internal_value
: serializer의 WRITE 모드 방향(역직렬화)to_representation
: serializer의 READ 모드 방향(직렬화)build_absolute_uri()
: FULL URL을 생성하는 메서드ListAPIView -> GenericAPIView(상위클래스) 확인
get_serializer_context()
: 여기서 context 변수로 'request', 'format', 'view'를 만들어주고 있음 -> 해당 함수의 request 부분을 None으로 바꾸면 보통 URL로 변경됨! (오버라이딩)ListAPIView를 상속받는 PostListAPIView에 get_serializer_context 함수 오버라이딩!
class PostListAPIView(ListAPIView):
queryset = Post.objects.all()
serializer_class = PostListSerializer
pagination_class = PostPageNumberPagination
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': None, ⭐
'format': self.format_kwarg,
'view': self
}
결과
https://www.inflearn.com/course/%EC%9E%A5%EA%B3%A0-drf/dashboard