● 페이징
페이징을 구현하기 전에 페이징을 테스트할 수 있을 정도로 충분한 데이터 생성이 필요하다.
대량의 테스트 데이터를 만드는 가장 좋은 방법은 장고셸을 이용하면 된다.
- 테스트 데이터 대량 상성
* 장고 셸 실행
(mysite) c:\projects\mysite>python manage.py shell
>>> from pybo.models import Question
>>> from django.utils import timezone
- 100개 데이터 생성
>>> for i in range(100):
... q = Question(subject='test data:[%03d]' % i, content='내용무', create_date=timezone.now())
... q.save() #엔터필수
...
>>> exit()
**
[%03d]
% : 문자열 포맷팅 연산자
0 : 해당 숫자를 0으로 채우라는 의미
3 : 최소한의 자리수이며, 위 내용은 세자리로 표시됨을 의미
ㄴ 숫자가 세자리 미만이면 앞에 0으로 채워진다.
d : 십진수 정수를 의미

**
100개의 데이터가 한 페이지에 생성된 것을 확인할 수 있다.
● Paginator
페이징을 위해 사용하는 클래스
[파일명: projects\mysite\pybo\views.py]
(.. 생략 ..)
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를 이용하여 요청된 페이지(page)에 해당되는 페이징 객체(page_obj) 생성했다.
이렇게 하면 장고 내부적으로는 데이터 전체를 조회하지 않고 해당 페이지의 데이터만 조회하도록 쿼리가 변경
※ 페이징 객체 page_obj 속성
| 항목 | 설명 |
| 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부터 시작) |
| 이 속성들은 템플릿에서 페이징을 처리할 때 사용된다. | |
- 템플릿에 페이지 적용
[파일명: projects\mysite\templates\pybo\question_list.html]
(.. 생략 ..)
</table>
<!-- pagin 처리 -->
<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 %}
<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 %}
{% 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, page-item, page-link 등이 부트스트랩 pagination 컴포넌트의 클래스
부트스트랩 pagination - https://getbootstrap.com/docs/5.1/components/pagination/
Pagination
Documentation and examples for showing pagination to indicate a series of related content exists across multiple pages.
getbootstrap.com
- 페이지 리스트
[파일명: projects\mysite\templates\pybo\question_list.html]
(... 생략 ...)
<!-- 페이지리스트 -->
{% 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 %}
(... 생략 ...)
**
|add:-5, |add:5 는 템플릿 필터 // |add:-5는 5만큼 빼라는 의미이고 |add:5는 5만큼 더하라는 의미
페이지 리스트가 현재 페이지 기준으로 좌우 5개씩 보이도록 만든다.
현재 페이지를 의미하는 question_list.number보다 5만큼 크거나 작은 값만 표시되도록 만들었다.
'Web > Django' 카테고리의 다른 글
| Django - 내비게이션바 (0) | 2024.05.27 |
|---|---|
| Django - 폼 (0) | 2024.05.21 |
| Django - 템플릿 상속 (0) | 2024.05.18 |
| Django - 부트스트랩 (0) | 2024.05.18 |
| Django - 스태틱 (0) | 2024.05.18 |























