본문 바로가기
python/Django

4. 게시판 만들기 - Django 템플릿 & 페이징(Pagination) 처리( feat. GIF )

by 맑은안개 2021. 2. 4.

전 편에 이어 게시판 필수 항목인 페이징 처리를 해보도록 한다. Django는 Paginator를 built-in module로 제공하는데 이를 사용하여 페이징 처리를 쉽게 구현할 수 있다.

 

1. 게시판 만들기 - Django 3.x 설치 및 핵심개념 파악

2. 게시판 만들기 - Django + mariaDB 연동( 접속부터 모델생성까지 )

3. 게시판 만들기 - Django 게시판 목록, 읽기, 쓰기 페이지 구성

 

board/views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.utils import timezone
from django.urls import reverse
from django.core.paginator import Paginator

from .models import Board

def index(request):
    all_boards = Board.objects.all().order_by("-pub_date") # 모든 데이터 조회, 내림차순(-표시) 조회
    paginator = Paginator(all_boards, 5)
    page = int(request.GET.get('page', 1))
    board_list = paginator.get_page(page)

    return render(request, 'board/index.html', {'title':'Board List', 'board_list':board_list})
    
.. 하단 생략 ..
  • Paginator(all_boards, 5) 글을 5개씩 출력한다.

  • request.GET.get('page', 1) index로 GET요청이 들어오면 page 파라미터를 읽는다. 없는 경우 1번째 페이지를 default로 셋트한다.

  • paginator.get_page(page) 는 class 'django.core.paginator.Page' 를 리턴한다. dir로 함수 구성을 살펴 보면 아래와 같다. 페이징 처리에 필요한 데이터(총 페이징 수, 현재 페이지 등)를 갖고 있다.

'count', 'end_index', 'has_next', 'has_other_pages', 'has_previous', 'index', 'next_page_number', 'number', 'object_list', 'paginator', 'previous_page_number', 'start_index'

 

 

board/templates/board/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style type="text/css">
        thead {
            background-color:#cecece;
        }

        .content {
            max-width:500px;
            margin: auto;
            padding:10px;
        }

        .header {
            text-align: center;
        }

        .board {
            width: 100%
        }

        .even_bgcolor {
            background-color:#e8efff;
        }

        .pagination {
            display: flex;           
        }

        .current {
            font-weight: bold;
        }

        a {
            text-decoration: none;
            text-align: center;
        }

        .abutton {
            background-color: #e6e6ff;
            color: #7b7b7b;
            font-size: small;
        }

    </style>
<body>
    <div class="content">
        <div class="header">
            <h2>{{ title }}</h2>
        </div>
        <div style="text-align:right">
            <a href="{% url 'board:write' %}">글쓰기</a>
        </div>

        <div style="height:280px;">
            <table class="board">
                <thead>
                    <tr class="header">
                        <th style="width:10%;">순번</th>
                        <th style="width:60%">제목</th>
                        <th style="width:30%">작성일자</th>
                    </tr>
                </thead>
                <tbody>
                {% if board_list %}
                    {% for data in board_list %}
                    <tr class="{% cycle '' 'even_bgcolor' %}">
                        <td style="text-align:center;">{{ forloop.counter }}</td>
                        <td>
                            <a href="{% url 'board:detail' data.id %}">
                                {{ data.title }}
                            </a>
                        </td>
                        <td>{{ data.pub_date|date:'Y-m-d' }}</td>
                    </tr>
                    {% endfor %}
                {% else %}
                    <tr>
                        <td>작성된 게시글이 없습니다.</td>
                    </tr>
                {% endif %}
                </tbody>
            </table>
        </div>

        <!-- Pagination -->
        <div style="text-align:center">
            <div class="pagination">
            
                <div style="width:35%; margin: 5px;">
                {% if board_list.has_previous %}
                    <a class="abutton" href="?page=1">맨 앞으로</a>
                    <a class="abutton" href="?page={{ board_list.previous_page_number }}">이전</a>
                {% endif %}
                </div>

                <div style="width:30%; margin: 5px;">
                {% for page in board_list.paginator.page_range %}
                    {% if page >= board_list.number|add:-2 and page <= board_list.number|add:2 %}
                    <span class="{% if page == board_list.number %}current{% endif %}">
                        <a href="?page={{ page }}">{{ page}}</a>
                    </span>
                    {% elif page >= board_list.number|add:-3 and page <= board_list.number|add:3 %}
                        ..
                    {% endif %}
                {% endfor %}
                </div>

                <div style="width:35%; margin: 5px;">
                {% if board_list.has_next %}
                    <a class="abutton" href="?page={{ board_list.next_page_number }}">다음</a>
                    <a class="abutton" href="?page={{ board_list.paginator.num_pages }}">맨 뒤로</a>
                {% endif %}
                </div>

            </div>  
        </div> 
    </div>
</body>
</html>
  • 페이징 뷰는 테이블 하단에 고정된 자리에 위치한다. 

  • 현재 페이지를 중심으로 앞뒤 2개의 페이지 수가 보여진다. add:-2, add:2

  • 현재 페이지를 중심으로 앞뒤 3개의 페이지는 .. 으로 표시한다. add:-3, add:3

 

게시판 페이징 시연 GIF

 

반응형