django - Pagination with JsonResponse

solee·2022년 3월 7일
1

Django

목록 보기
9/12

django paginator를 처음 본 나
우와~!!!! 얘가 알아서 계산해준대!!



django paginator로 JsonResponse를 할 수 없어진 나
계산기... 계산기 어딨지?



우냐고? 안 운다...(아마도)

스포일러 알랏 : 해결할것이다!





작성했던 코드다.

하고 싶었던 것:
1. 상품 리스트를 리턴한다.
2. 카테고리 필터링 및 정렬을 해 준다.
3. 페이징을 해 준다.

페이지네이터를 보고 얼른 해 보고 싶어서 일단 간단하게 짜 본 코드다. 아직 프론트와 어떤 정보를 나눠야 하는지도 알 수 없다. 상관없다고 생각했다.
그런데... 에러가 났다.



앗? ㅎㅎ 어라 이상하다? 왜 return에서 에러가 나지?

ㅎㅎ?

...ㅎ?



TypeError: Object of type range is not JSON serializable
요 타입 에러는 심심찮게 본 적 있다. JsonResponse가 리턴할 수 없는 종류의 객체라는 뜻이다.
그러니까... json이 아니라는 거지.

다른 때였으면 그렇구나 하고 원인을 찾았을텐데, 이상했다. result는 애초에 list인데?
그 안에 들어가는 친구도? 쿼리셋인데? 혹시 싶어서 끝에 .values()를 붙이고 list로 형변환도 해 봤다. 나오는 데이터 모양이 달라지는 정도고(물론 이건 만족스럽지만), paginator가 안 먹혔다.


그래서 paginator를 출력해 봤더니...

<Page 1 of 3>

..?

<class 'django.core.paginator.Page'>

너구나.....

해서 조금 더 알아보니, Pagination이 기본적으로 django Template으로 데이터를 보내기 위한 객체를 반환하기 때문에 JsonResponse로는 TypeError가 발생하는 것이다.

찾아보니 render를 해 줬다는 사람이 있어서, django 문서에도 그렇고 보통 return으로 render(~)를 해 주었던 게 기억나서 그걸 찾아보았다.
그런데... 작고 귀여운 문제가 발생했다(항상 그렇지 뭐!)

render(request, template_name, context=None, content_type=None, status=None, using=None)

그렇다... render()는... 템플릿을 인자로 받는다.
나는.. 템플릿이 없다.
나는 입구컷을 당한 것이다.



해결책

하지만 죽으라는 법은 없는 모양이다. 공식문서에서 답을 찾았다!
https://docs.djangoproject.com/en/4.0/ref/paginator/#django.core.paginator.Paginator

할렐루야!!!
그래서 page에 .object_list를 해 보았더니???

이런것이 출력되었다.

paginator = Paginator(product_list, 12)
<QuerySet [
<Product: Product object (45)>, <Product: Product object (46)>, <Product: Product object (47)>, 
<Product: Product object (48)>, <Product: Product object (49)>, <Product: Product object (50)>,
<Product: Product object (51)>, <Product: Product object (52)>, <Product: Product object (53)>, 
<Product: Product object (54)>, <Product: Product object (55)>, <Product: Product object (56)>
]>

원래 작성했던 코드를 기준으로 하면 paginator.object_list를 리턴하면 됐을 것이다.
사실 나 혼자 한 건 아니고... 공식 문서를 읽어보라고 추천받고도 뭘 봐야 할지 몰랐지만(ㅠㅠ)
드디어 행복이 찾아온 것이다.





안타까운 점은 내가... paginator를 포기하고 이미 다른 방식을 썼다는 거다.

많은 일이 있었는데,

  • 일단 메서드가 get으로 바뀌었다. 쿼리스트링으로 데이터를 전달받기 때문에 request.GET.get()을 사용한다.
  • page, offset 등을 입력받고 계산해서 카테고리에 따라 필요한 데이터를 필터링해서 정렬한 후 offset과 limit에 따라 원하는 페이지만큼 데이터를 꺼내 return한다.
  • 프론트의 요청으로 여러 데이터들을 results에 담지 않고 보내게 되었다.

아마 내가 정보를 찾을 수 없었던 건.. 내가 구글링을 거지같이 했거나... 아는 사람들은 글을 쓸 필요를 못 느꼈고 모르는 사람들이 템플릿으로 렌더하라는 방법을 추천해 주고 있던 그런 상황이 아닐까 생각한다. 처음부터 JsonResponse가 아니라 리스트로 출력하는 방법으로 찾아봤으면 금방 찾았을까? 그냥.. JsonResponse를 찾는 사람들에게는 object_list를 아무도 추천해 주지 않은 것이다...

음.
오케이.

profile
DA DA DA

0개의 댓글