기록과 정리의 공간

[프로젝트] Flask로 게시판 만들기 - 3 본문

프로젝트/게시판1

[프로젝트] Flask로 게시판 만들기 - 3

딸기맛도나쓰 2020. 8. 1. 16:24

Flask로 게시판 만들기 - 3 (참고 강의 링크-인프런 강의)
(공부 하며 기록이 필요한 부분들만 정리함)

  • 개발 환경 : windows 10 / Python 3.8.1 / vscode
  1. jinja문법을 사용하여 게시물 번호 매기기
  2. 게시물 리스트 pagination(페이지네이션) 구현하기

1. jinja문법을 사용하여 게시물 번호 매기기

  • for문 블럭안에서 사용할 수 있는 특별한 variables 몇 가지 (링크) (링크 접속 후 컨트롤 + f 로 loop.index 검색 후 3번째 loop.index 부분에 정리되어있음)

    Variable  Description
    loop.index 1부터 시작해서 현재 반복 횟수를 나타냄
    loop.index0 0부터 시작
    loop.length 전체 반복 횟수 나타냄
# 예시

{% if datas.count() > 0 %}
{% for data in datas %} 
<tr>
    <td>{{loop.index}}</td> # 게시물 번호 매기기
    <td><a href="{{url_for('board_view', idx=data._id)}}">{{data.title}}</a></td>
    <td>{{data.name}}</td>
    <td>{{data.pubdate|formatdatetime}}</td>
    <td>{{data.view}}</td>
    </tr>
{% endfor %}
{% else %}
<h3>데이터가 존재하지 않습니다.</h3>
{% endif %}

2. 게시물 리스트 pagination(페이지네이션) 구현하기 (전체 코드x, 일부 코드만 가져옴)

  • pagination = page + navigation
  • 페이징을 위한 여러 라이브러리들이 있지만, 원리를 파악하기 위해 직접 구현해보도록 하자.
  • skip(), limit() 사용(pymongo - skip(), limit() 설명 링크) (컨트롤 + f 후 skip()검색)
    • skip() : 인자로 주어진 숫자 만큼 documents를 skip함.
    • limit() : 인자로 주어진 숫자 만큼 documents를 보여줌.

0) 구현하고자 하는 형태 (결과 화면)

1) 한 페이지 당 출력할 게시물 수 제한하기

  • limit : 한 페이지 당 출력한 게시물 개수를 10개로 정함
  • board.find({}) : board컬렉션에 저장된 모든 데이터를 가져옴.
  • skip((page - 1) * limit).limit(limit) : 만약 page값이 2라면 skip(10).limit(10) 이 되므로, skip되는 게시물은 10개이며 한 페이지당 게시물 10로 제한 되므로, board컬렉션의 맨 처음 데이터를 포함하여 순서대로 10개의 게시물이 skip되고 11번째 데이터 부터 20번째 데이터까지가 보여지게 됨.

2) 나머지 설명은 아래 코드의 주석들 확인

@app.route("/list")
def board_list():
    board = mongo.db.board
    # 페이지 값 (디폴트값 = 1)
    page = request.args.get("page", 1, type=int)
    # 한 페이지 당 몇 개의 게시물을 출력할 것인가
    limit = 10

    datas = board.find({}).skip((page - 1) * limit).limit(limit)  # board컬럭션에 있는 모든 데이터를 가져옴

    # 게시물의 총 개수 세기
    tot_count = board.find({}).count()
    # 마지막 페이지의 수 구하기
    last_page_num = math.ceil(tot_count / limit) # 반드시 올림을 해줘야함

    # 페이지 블럭을 5개씩 표기
    block_size = 5
    # 현재 블럭의 위치 (첫 번째 블럭이라면, block_num = 0)
    block_num = int((page - 1) / block_size)
    # 현재 블럭의 맨 처음 페이지 넘버 (첫 번째 블럭이라면, block_start = 1, 두 번째 블럭이라면, block_start = 6)
    block_start = (block_size * block_num) + 1
    # 현재 블럭의 맨 끝 페이지 넘버 (첫 번째 블럭이라면, block_end = 5)
    block_end = block_start + (block_size - 1)
    return render_template(
        "list.html",
        datas=datas,
        limit=limit,
        page=page,
        block_start=block_start,
        block_end=block_end,
        last_page_num=last_page_num)
<!-- list.html -->

{% if datas.count() > 0 %}
<table>
    <thead>
        <tr>
            <td>번호</td>
            <td>제목</td>
            <td>이름</td>
            <td>날짜</td>
            <td>조회수</td>
        </tr>
    </thead>
    <tbody>
        <!-- 반복되는 구간 -->
        {% for data in datas %}
        <tr>
            <!-- 게시물 순서대로 번호 부여하기 -->
            <td>{{loop.index + (page - 1) * limit}}</td>
            <td><a href="{{url_for('board_view', idx=data._id)}}">{{data.title}}</a></td>
            <td>{{data.name}}</td>
            <td>{{data.pubdate|formatdatetime}}</td>
            <td>{{data.view}}</td>
        </tr>
        {% endfor %}
        <!-- 반복되는 구간 끝 -->
    </tbody>
</table>

<!-- 페이지네이션을 위한 코드 시작 -->
{% if block_start - 1 > 0 %}
    <a href="{{url_for('board_list', page=block_start - 1)}}">[이전]</a>
{% endif %}

{% for i in range(block_start, block_end + 1)%}
    <!-- 데이터가 존재하지 않는 페이지는 화면에 나타내지 않기 위한 조건문 -->
    {% if i > last_page_num %}

    {% else %}
        {% if i == page %}
            <b>{{ i }}</b>
        {% else %}
            <a href="{{url_for('board_list', page=i)}}">{{ i }}</a>
        {% endif %}
    {% endif %}
{% endfor %}

{% if block_end < last_page_num %}
    <a href="{{url_for('board_list', page=block_end + 1)}}">[다음]</a>
{% endif %}
<!-- 페이지네이션을 위한 코드 끝 -->

{% else %}
<h3>데이터가 존재하지 않습니다.</h3>
{% endif %}
Comments