django

django rest framework pagination 안 되는 문제 해결

발전생 2021. 2. 7. 11:35

django rest framework 사용 중 페이지네이션 기능을 원했지만 APIView나 GenericApiView 사용 시 자동으로 pagination이 되지 않고 queryset 전체를 한 번에 가져왔다. 물론 pagination_class도 코드에 포함했었다.

 

아래는 공식 홈페이지에서 발췌한 글이다. GenericApiView는 자동으로 페이지네이션을 안 해준단다. 그래서 viewsets를 사용했더니 자동으로 response에 page_size만큼 데이터를 전달해준다. previous 링크랑 next 링크 주소도 전달해줘서 api로 사용하기에 손색이 없다. 처음에는 apiview라는 이름이 안 들어가서 apiview 방법을 고집해봤지만 쉽게 해결이 안 돼서 viewsets를 사용했는데 api랑 크게 다르지 않다.

 

Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular 
APIView
, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the 
mixins.ListModelMixin and enerics.GenericAPIView classes for an example.

출처: www.django-rest-framework.org/api-guide/pagination/#pagination

 

Pagination - Django REST framework

pagination.py Django provides a few classes that help you manage paginated data – that is, data that’s split across several pages, with “Previous/Next” links. — Django documentation REST framework includes support for customizable pagination styl

www.django-rest-framework.org

 

 

class SentenceViewSet(ReadOnlyModelViewSet):
    """ 키워드에 해당하는 리뷰 문장을 보여주기 위한 viewset """
    serializer_class = SentenceSerializer
    pagination_class = PageNumberPagination

    def get_queryset(self):
        // 구현

 

 

이렇게 viewsets를 사용했다.

 

아래는 response이다. previous 링크랑 next 링크를 같이 전달해 주기 때문에 프론트 단에서 연결시켜 주기도 쉽다. 

아쉬운 점은 django에서는 page range나 현재 페이지 번호를 템플릿에서 유용하게 사용할 수 있는데 rest framework에서는 사용을 원할 경우 직접 구현해야 할 거 같다.

 

 

 

이건 크게 상관은 없는 내용이지만 페이지네이션과 함께 괴롭혔던 부분이 있어서 기록한다.

ManyRelatedManager object is not subscriptable 해당 에러가 날 괴롭혔다.

review.positive_keyword.get(name=keyword).sentence

Keyword 모델에 sentence가 ManyToManyField로 정의되어 있는 상황이다.

위 코드를 사용하면 리턴 값은 ManyRelatedManager object이다.

원하던 건 Sentence 모델의 queryset이었다.

맨 끝에 .all()을 붙여줬더니 정상적으로 queryset을 잘 가져왔다.

해당 error를 구글에 검색 했는데도 일치하는 결과가 딱 하나밖에 없었다. 자주 하는 실수는 아닌가 보다.