게시판 페이징 기능

책 '점프 투 플라스크'를 공부하면서 정리한 내용입니다.
출처 : https://wikidocs.net/book/4542

게시판 페이징 기능 추가하기

게시물이 들어날 수록 한 화면에 표시할 게시물이 많아져 스크롤 바를 내려야 하는 불편함이 생기기 때문에 페이징 기능은 필수이다.

임시 질문 데이터 300개 생성

플라스크 셸을 이용해 페이징 테스트용 데이터 300개 생성

>>> from pybo import db
>>> from pybo.models import Question
>>> from datetime import datetime

>>> for i in range(300):
...     q = Question(subject='테스트 데이터입니다:[%03d]' % i, content='내용무', create_date=datetime.now())
...     db.session.add(q)
...
>>>  db.session.commit()

페이징 기능 구현

1. views/question_views.py 파일에 페이징 기능 구현

_list 함수에 페이징 기능 적용

@bp.route('/list/')
def _list():
# --------------------------------- [edit] ---------------------------------- #
    page = request.args.get('page', type=int, default=1)  # 페이지
# --------------------------------------------------------------------------- #
    question_list = Question.query.order_by(Question.create_date.desc())
# --------------------------------- [edit] ---------------------------------- #
    question_list = question_list.paginate(page, per_page=10)
# --------------------------------------------------------------------------- #
    return render_template('question/question_list.html', question_list=question_list)

다음과 같은 GET 방식으로 요청한 URL에서 page값 5를 가져올 때 사용한다.
localhost:5000/question/list/?page=5

URL에 page값이 없으면 default=1을 자동으로 적용해 기본값 1이 설정되고, type=int는 page 매개변수의 자료형이 정수임을 의미한다.

  • paginate 함수
    • 조회한 데이터 question_list에 paginate 함수로 페이징을 적용
    • 1번째 인자로 전달된 page는 현재 조회할 페이지의 번호를 의미하고, 2번째 인자 per_page로 전달된 10은 페이지마다 보여 줄 게시물이 10건임을 의미
    • 조회한 데이터를 감싸 Pagination 객체로 반환
    • question_list는 paginate 함수를 사용해 Pagination 객체가 되었으므로 다음과 같은 속성을 사용할 수 있다.

템플릿에 페이징 적용

1. question/question_list.html 파일의 질문 목록 출력 코드 수정

템플릿에서 사용하는 question_list가 Pagination 객체로 변경되었으므로 .items를 추가하는 방식으로 수정

현재 조회된 질문목록 데이터’를 가져오려면 items 함수를 호출

 {% for question in question_list.items %}

기본값이 page=1에 의해 첫 번째 페이지가 10개의 목록을 출력하는 것을 볼 수 있다.

페이지 이동 기능 추가

	<!-- 페이징처리 시작 -->
    <ul class="pagination justify-content-center">

        <!-- 이전페이지 -->
        {% if question_list.has_prev %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.prev_num }}">이전</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">이전</a>
        </li>
        {% endif %}

        <!-- 페이지 리스트를 돌면서 해당 페이지로 이동할 수 있는 링크 -->
        {% for page_num in question_list.iter_pages() %}
            {% if page_num %}
                {% if page_num != question_list.page %}
                <li class="page-item">
                    <a class="page-link" href="?page={{ page_num }}">{{ page_num }}</a>
                </li>
                {% else %}
                <li class="page-item active" aria-current="page">
                    <a class="page-link" href="#">{{ page_num }}</a>
                </li>
                {% endif %}
           {% else %}
                <li class="disabled">
                    <a class="page-link" href="#">...</a>
                </li>
           {% endif %}
        {% endfor %}


        <!-- 다음페이지 -->
        {% if question_list.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.next_num }}">다음</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">다음</a>
        </li>
        {% endif %}
    </ul>
    <!-- 페이징처리 끝 -->

부트스트랩 pagination 컴포넌트 공식 문서: getbootstrap.com/docs/4.5/components/pagination

생략 기능까지 완벽한 paginate 함수
iter_pages 함수로 페이지가 나열될 때 페이지 번호(page_num)가 없는 경우 '...'를 표시. 보여줄 페이지 번호가 지나치게 많은 경우 현재 페이지 위주로 보여주는 기술.

좋은 웹페이지 즐겨찾기