웹 클론 프로젝트를 진행하던 중 pagination에 대한 학습이 필요하여 그에 대해 공부해보고 작성하는 글이다. 또한 이 pagination에 방법엔 세가지가 있는데 그 중 학습한 두가지 방법의 차이에 대해 작성한다.
(진행 중인 프로젝트의 코드로 작성하였습니다.)
1 2 3 4 5 6 7 8 9 | page = request.GET.get('page', 1) page = int(page or 1) page_size = 24 limit = page_size * page offset = limit - page_size products = Product.objects.all()[offset:limit] page_count = ceil(Product.objects.count() / page_size) return JsonResponse({'product': products, 'page': page, 'page_count': page_count, 'page_range': range(1, page_count)}, status=200) | cs |
(1번 줄) URL에 입력된 page를 가져온다. (2번 줄)page가 없다면 1을 저장한다. (3번 줄)페이지의 크기를 24로 지정해 준다. (4번 줄)페이지의 데이터 크기(인덱스의 마지막값)을 지정해준다. (5번 줄) 페이지의 시작(인덱스의 첫번째 값)을 지정해준다.
1 2 3 4 5 6 7 8 | from django.core.paginator import Paginator ... page = request.GET.get('page') products = Product.objects.all().order_by('-id') paginator = Paginator(products, 24) posts = paginator.get_page(page) return JsonResponse({'products': posts.object_list}, status=200) | cs |
django의 모듈인 paginator를 사용하여 작성한 코드이다. (3번 줄)URL에 입력된 page를 가져온다. (5번 줄) ORM을 통해 가져온 products를 24개의 데이터로 나눠서 paginator에 저장한다. (6번 줄)get_page로 현재 가져온 page의 데이터를 posts에 저장해 준다. (7번 줄)post에 저장된 데이터들을 object_list를 통해 return해준다.
둘 다 가능한 방법이고 똑같은 결과를 보여준다. 하지만 굳이 1번과 같은 방법이 있는데 코드를 조금 줄이기 위해서 2번의 모듈을 만들어 낸 것일까?
눈에는 보이지 않지만 아주 큰 차이가 있다.
이는 두 코드의 응답 시간에서 찾을 수 있다.
적은 양의 데이터에서는 두 코드의 응답시간에는 별 다른 차이점이 존재하지 않지만 데이터량이 많아질수록 그 차이는 점점 선명해진다.
참고 - 김상민님의 장고 데이터베이스 페이징 성능 개선
위의 김상민님의 글에 자세히 설명되어 있다. 또한 이와 관련해서 Django의 공식 문서에서 찾아 볼 수 있다.
Django
Performance issues paginating large QuerySets
If you’re using a QuerySet with a very large number of items, requesting high page numbers might be slow on some databases, because the resulting LIMIT/OFFSET query needs to count the number of OFFSET records which takes longer as the page number gets higher.