[TIL | 240109] Django - 페이징(Paging)

sun_U·2024년 1월 11일
0

TIL

목록 보기
15/21
post-thumbnail

페이징 (paging)


1. 대량 테스트 데이터 생성

  • 장고 셸 활용해 데이터(게시물) 대량 생생

> python [manage.py](http://manage.py) shell

from django.utils import timezone
from pybo.models import Question

for i in range(300):
	q = Question(subject='테스트 데이터입니다 : [%03d]' %i,content='내용무', create_date=timezone.now())
	q.save()
  • 300개 이상의 데이터가 한 페이지에 보여짐

2. Paginator

  • 페이징을 위해 사용하는 클래스

pybo/views.py

from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from .models import Question
from .forms import QuestionForm, AnswerForm
from django.core.paginator import Paginator  

def index(request):
    page = request.GET.get('page', '1')  # 페이지
    question_list = Question.objects.order_by('-create_date')
    paginator = Paginator(question_list, 10)  # 페이지당 10개씩 보여주기
    page_obj = paginator.get_page(page)
    context = {'question_list': page_obj}
    return render(request, 'pybo/question_list.html', context)

(... 생략 ...)
  • page = request.GET.get('page', '1') - http://localhost:8000/pybo/?page=1 처럼 GET 방식으로 호출된 URL에서 page값을 가져올 때 사용.  http://localhost:8000/pybo/ 처럼 page값 없이 호출된 경우 디폴트값 1
  • paginator = Paginator(question_list, 10) - (게시물 전체, 페이지 당 보여줄 게시물 개수)
  • page_obj = paginator.get_page(page) - 페이지에 해당되는 페이징 객체
  • 페이징 객체 속성
    항목설명
    paginator.count전체 게시물 개수
    paginator.per_page페이지당 보여줄 게시물 개수
    paginator.page_range페이지 범위
    number현재 페이지 번호
    previous_page_number이전 페이지 번호
    next_page_number다음 페이지 번호
    has_previous이전 페이지 유무
    has_next다음 페이지 유무
    start_index현재 페이지 시작 인덱스(1부터 시작)
    end_index현재 페이지의 끝 인덱스(1부터 시작)

3. 템플릿에 페이징 적용하기 & 페이지 리스트

  • question_list.html 에 페이징 객체(question_list)가 전달됨

question_list.html 페이징 처리

(... 생략 ...)
    </table>
    <!-- 페이징처리 시작 -->
    <ul class="pagination justify-content-center">
        <!-- 이전페이지 -->
        {% if question_list.has_previous %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.previous_page_number }}">이전</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">이전</a>
        </li>
        {% endif %}
        <!-- 페이지리스트 -->
        {% for page_number in question_list.paginator.page_range %}
				{% if page_number >= question_list.number|add:-5 and page_number <= question_list.number|add:5 %}
        {% if page_number == question_list.number %}
        <li class="page-item active" aria-current="page">
            <a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
        </li>
        {% else %}
        <li class="page-item">
            <a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
        </li>
        {% endif %}
				{% endif %}
        {% endfor %}
        <!-- 다음페이지 -->
        {% if question_list.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.next_page_number }}">다음</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">다음</a>
        </li>
        {% endif %}
    </ul>
    <!-- 페이징처리 끝 -->
    <a href="{% url 'pybo:question_create' %}" class="btn btn-primary">질문 등록하기</a>
</div>
{% endblock %}
  • 이전 페이지가 있는 경우 “이전”링크 활성화, 없으면 비활성화
    페이징 기능코드
    이전 페이지가 있는지 체크{% if question_list.has_previous %}
    이전 페이지 번호{{ question_list.previous_page_number }}
    다음 페이지가 있는지 체크{% if question_list.has_next %}
    다음 페이지 번호{{ question_list.next_page_number }}
    페이지 리스트 루프{% for page_number in question_list.paginator.page_range %}
    현재 페이지와 같은지 체크{% if page_number == question_list.number %}
  • 부트스트랩의 pagination 컴포넌트 이용
  • {% if page_number >= question_list.number|add:-5 and page_number <= question_list.number|add:5 %} - question_list.number (현재 페이지) 보다 5만큼 크거나 작은 값만 표시

profile
Data Engineer🐣

0개의 댓글