[Flask] 3-2 게시판 페이징

2023. 12. 2. 18:52ㆍWeb/Flask

728x90

지금까지 만든 파이보의 질문 목록은 페이징(paging) 기능이 없었다

만약 페이징 기능이 없으면

게시물이 300개 작성되면 질문 목록 화면에 게시물이 300개 그대로 표시될 것이다

 이런 경우 한 화면에 표시할 게시물이 많아져서 스크롤 바를 내려야 하는 등의

불편함이 생기므로 페이징 기능은 필수다

 

임시 질문 데이터 300개 생성하기

페이징을 구현하기 전에 페이징을 테스트할 정도로 데이터를 충분히 생성하자

여기서는 테스트 데이터를 300개 생성한다

테스트 데이터를 대량으로 만드는 가장 좋은 방법은 플라스크 셸을 이용하는 것이다

 

질문 데이터를 생성하기 위한 모듈을 import 하고

for 문을 이용하여 다음처럼 테스트 데이터를 300개 생성하자

 

이제 플라스크 셸을 종료하고 로컬 서버를 실행한 다음 브라우저에서 질문 목록을 보자

플라스크 셸로 등록한 테스트 데이터가 보일 것이다

그리고 300개 이상의 데이터가 한 페이지에 보여지는 것을 확인할 수 있다

이러한 이유로 페이징은 반드시 필요하다

 

페이징 구현하기

views/question_views.py 파일을 열어 _list 함수에 아래처럼 페이징을 적용하자

 페이징은 paginate 함수를 사용하여 쉽게 구현할 수 있다

[파일명: projects/myproject/pybo/views/question_views.py]

page = request.args.get('page', type=int, default=1)는 아래와 같은 GET 방식으로

요청한 URL에서 page값을 가져올 때 사용한다

만약 아래와 같이 URL에 page값이 없으면 default=1을 적용해 기본값 1이 설정된다

question_list = question_list.paginate(page=page, per_page=10)는

조회한 데이터 question_list에 paginate 함수로 페이징을 적용한다

 함수의 1번째 인수로 전달된 page는 현재 조회할 페이지의 번호를 의미하고,

2번째 인수 per_page로 전달된 10은 페이지마다 보여 줄 게시물이 10건임을 의미한다

 

paginate 함수를 적용하면 Pagination 객체가 리턴되어 아래와 같은 속성들을 사용할 수 있게 된다

항목 설명 값의 예
items 현재 페이지에 해당하는 게시물 리스트 [<Question 282>,<Question 283>, ...]
total 게시물 전체 개수 302
per_page 페이지당 보여 줄 게시물 개수 10
page 현재 페이지 번호 2
iter_pages 페이지 범위 [1, 2, 3, 4, 5, None, 30, 31]
prev_num / next_num 이전 페이지 번호 / 다음 페이지 번호 현재 페이지가 3인 경우, 2 / 4
has_prev / has_next 이전 페이지 존재 여부 / 다음 페이지 존재 여부 True / False

paginate 함수를 사용하면 별다른 수고없이 위의 속성들을 사용할 수 있어 페이징 처리가 쉬워진다

 

템플릿에 페이징 적용해 보기

이제 Pagination 객체의 속성들을 사용하여 템플릿에서 어떻게 페이징을 처리하는지 알아보자

 

질문 목록 출력 코드 수정하기

먼저 템플릿에서 사용하는 question_list가 Pagination 객체로 변경되었으므로

목록을 출력하는 부분을 다음과 같이 수정해야 한다

[파일명: projects/myproject/pybo/templates/question/question_list.html]

원래 코드인 {% for question in question_list %}를 {% for question in question_list.items %} 처럼

.items 를 추가하여 수정해 주었다

Pagination객체는 현재 조회된 목록데이터를 가져오기 위해서는 items 함수를 호출해야 한다

 

이제 질문 목록 페이지에 접속하면 이제 질문 데이터 300건이 한꺼번에 표시되지 않고 페이징 기능으로 한 페이지에 10건씩 출력되는 것을 확인할 수 있다

 

페이지 이동 기능 추가로 페이징 기능 완성하기

이번에는 페이지 이동 기능을 추가해 보자

question_list.html 템플릿의 </table> 바로 아래에 다음과 같이 코드를 추가하자

[파일명: projects/myproject/pybo/templates/question/question_list.html]

상당히 많은 양의 HTML코드가 추가되었지만 어렵지 않으니 천천히 보자

이전 페이지가 있는 경우에는 "이전" 링크가 활성화되게 하였고 이전 페이지가 없는 경우에는

"이전" 링크가 비활성화되도록 하였다

그리고 페이지 리스트를 루프 돌면서 해당 페이지로 이동할 수 있는 링크를 생성하였다

이때 현재 페이지와 같을 경우에는 active클래스를 적용하여 강조표시도 해 주었다

페이징 기능코드

페이징 기능코드
이전 페이지가 있는지 체크 {% if question_list.has_prev %}
이전 페이지 번호 {{ question_list.prev_num }}
다음 페이지가 있는지 체크 {% if question_list.has_next %}
다음 페이지 번호 {{ question_list.next_num }}
페이지 리스트 루프 {% for page_num in question_list.iter_pages() %}
현재 페이지와 같은지 체크 {% if page_num != question_list.page %}

 

그리고 페이지 리스트를 보기 좋게 표시하기 위해 부트스트랩의 pagination 컴포넌트를 이용하였다

템플릿에 사용한 pagination, page-item, page-link 등이 부트스트랩 pagination 컴포넌트의 클래스이다

 

paginate 함수가 없었다면 아마 이렇게 쉽게 해내기는 힘들었을 것이다

728x90